Skip to content

Implicit view not found involving an uninstantiated type variable #3343

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

Closed
allanrenucci opened this issue Oct 17, 2017 · 4 comments
Closed

Comments

@allanrenucci
Copy link
Contributor

This fails to compile with Dotty

class Test {
  implicit def implicitContainer[C[_], T](
    implicit t: C[T] => Traversable[T]): C[T] = ???

  implicitly[List[Char]]
}
-- Error: tests/allan/Test.scala:5:24 ------------------------------------------
5 |  implicitly[List[Char]]
  |                        ^
  |no implicit argument of type scala.collection.immutable.List[Char] found for parameter e of method implicitly in object Predef

Note that this compiles:

class Test {
  implicitly[List[Char] => Traversable[Char]]
}
@smarter
Copy link
Member

smarter commented Oct 17, 2017

I think you may have minimized this too much, this only succeeds in scalac because C[_] is instantiated to Nothing which is not something we'd like to have in dotty since C[_] is higher-kinded and Nothing isn't.

@allanrenucci
Copy link
Contributor Author

allanrenucci commented Oct 17, 2017

class Arbitrary[T]

object Arbitrary {
  def arbitrary[T](implicit a: Arbitrary[T]): T = ???

  implicit def arbContainer[C[_],T](implicit t: C[T] => Traversable[T]): Arbitrary[C[T]] = ???

  val arbString = arbitrary[List[Char]]
}

scalac resolves:

val arbString: List[Char] =
  arbitrary[List[Char]](arbContainer[List, Char](scala.Predef.$conforms[List[Char]]));

@smarter
Copy link
Member

smarter commented Oct 17, 2017

Thanks! We can reduce it further, this doesn't compile with dotty:

object Test {
  def foo[C[_],T](implicit t: C[T] => Traversable[T]): C[T] = ???

  val a: List[Char] = foo
}

But this does:

object Test {
  def foo[C[_],T](implicit t: C[T] => Traversable[T]): C[T] = ???

  val a: List[Char] = foo[List, Char]
}

The error we get in the first case is:

4 |  val a: List[Char] = foo
  |                         ^
  |        No implicit view available from scala.collection.immutable.List[T]
  |        
  |        where:    T is a type variable with constraint <: Char
  |         => scala.collection.Traversable[T]
  |        
  |        where:    T is a type variable with constraint <: Char
  |        .

@smarter smarter changed the title Failed implicit resolution Implicit view not found involving an uninstantiated type variable Oct 17, 2017
@smarter
Copy link
Member

smarter commented Oct 17, 2017

We can minimize even more actually:

object Test {
  def foo[C[_]](implicit t: C[Char] => Traversable[Char]): C[Char] = ???

  val a: List[Char] = foo
}
4 |  val a: List[Char] = foo
  |                         ^
  |No implicit view available from scala.collection.immutable.List[Char] => scala.collection.Traversable[Char].

Here the error message is misleading: there is an implicit view from List[Char] to Traversable[Char], the issue is that at the time we do the search we're looking for a view from C[Char] to Traversable[Char], but C gets instantiated before we print the error.

smarter added a commit to dotty-staging/dotty that referenced this issue Oct 17, 2017
Previously,
    `C[Char]`.baseType(`Traversable[Char]`)
    where C := `[X] => List|X]`
returned `Traversable[ParamRef(A)]` instead of `Traversable[Char]`,
because the substitution was done on the type parameters of the class
symbol instead of the type parameters of the type, these are different
when type lambdas are involved.
smarter added a commit to dotty-staging/dotty that referenced this issue Oct 17, 2017
Previously,
    `C[Char]`.baseType(`Traversable[Char]`)
    where C := `[X] => List|X]`
returned `Traversable[ParamRef(A)]` instead of `Traversable[Char]`,
because the substitution was done on the type parameters of the class
symbol instead of the type parameters of the type, these are different
when type lambdas are involved.
smarter added a commit to dotty-staging/dotty that referenced this issue Oct 17, 2017
Previously,
    `C[Char]`.baseTypeOf(`Traversable[Char]`)
    where C := `[X] => List|X]`
returned `Traversable[ParamRef(A)]` instead of `Traversable[Char]`,
because the substitution was done on the type parameters of the class
symbol instead of the type parameters of the type, these are different
when type lambdas are involved.
smarter added a commit to dotty-staging/dotty that referenced this issue Oct 17, 2017
Previously,
    `C[Char]`.baseTypeOf(`Traversable[Char]`)
    where C := `[X] => List[X]`
returned `Traversable[ParamRef(A)]` instead of `Traversable[Char]`,
because the substitution was done on the type parameters of the class
symbol instead of the type parameters of the type, these are different
when type lambdas are involved.
smarter added a commit to dotty-staging/dotty that referenced this issue Oct 18, 2017
Previously,
    `C[Char]`.baseTypeOf(`Traversable[Char]`)
    where C := `[X] => List[X]`
returned `Traversable[ParamRef(A)]` instead of `Traversable[Char]`,
because the substitution was done on the type parameters of the class
symbol instead of the type parameters of the type, these are different
when type lambdas are involved. This is fixed by always going through
`AppliedType#superType` when the tycon is not a class.
allanrenucci added a commit that referenced this issue Oct 19, 2017
Fix #3343: Make baseType work properly with type lambdas
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

2 participants