Skip to content

implicit summon fails in dotty, works in 2.* #1857

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
drdozer opened this issue Dec 24, 2016 · 1 comment
Closed

implicit summon fails in dotty, works in 2.* #1857

drdozer opened this issue Dec 24, 2016 · 1 comment

Comments

@drdozer
Copy link

drdozer commented Dec 24, 2016

The code below compiles and runs under 2.11.8 and 2.12.1, but fails under dotty with:

[info] Compiling 1 Scala source to /home/nmrp3/devel/turingatemyhamster/commandeer/target/scala-2.11/classes...
/home/nmrp3/devel/turingatemyhamster/commandeer/src/main/scala/commandeer/RunMe.scala:32: error: no implicit argument of type DSL found for parameter dsl of method apply in object CommandeerDSL
    val kevin = CommandeerDSL(null.asInstanceOf[Foo])
                                                     ^
/home/nmrp3/devel/turingatemyhamster/commandeer/src/main/scala/commandeer/RunMe.scala:34: error: value Bar is not a member of Nothing(kevin)
    val bar = kevin.Bar("bob", 3)
                    ^
two errors found
[error] (compile:compileIncremental) Compilation failed

I'm attempting to summon an implicit instance of a trait, but getting back type information specific to the instance that I've summoned, beyond that in the trait that I summoned it through. There may be a better way to do this with dotty, but I don't know it.

package commandeer


trait CommandeerDSL[Host] {
  trait Operation[T]
  type Op[T] <: Operation[T]
}

object CommandeerDSL {
  def apply[Host, DSL <: CommandeerDSL[Host]](host: Host)(implicit dsl: DSL): DSL = dsl
}
 
trait Foo {
  def bar(a: String, b: Int): Double
}
 
object Foo {
  implicit val fooDSL: FooDSL = new FooDSL {}
}
 
trait FooDSL extends CommandeerDSL[Foo] {
  sealed trait FooOperation[T] extends Operation[T]
  type Op[T] = FooOperation[T]

  case class Bar(a: String, b: Int) extends FooOperation[Double]
}
 
object RunMe {
  def main(args: Array[String]): Unit = {
    println("Hi Mum")

    val kevin = CommandeerDSL(null.asInstanceOf[Foo])
    println(s"Found DSL for Foo: $kevin")
    val bar = kevin.Bar("bob", 3)
    println(s"Made a bar: $bar")
  }
}
odersky added a commit to dotty-staging/dotty that referenced this issue Dec 25, 2016
Interpolating type variables before resolving implicit parameters means that
more companion objects can become eligible for the implicit scope. An example
demonstrating this is i1857.scala. The spec mandates this behavior because it
says that type arguments are inferred before implicit parameter resolution takes place.
@odersky odersky self-assigned this Dec 25, 2016
@odersky
Copy link
Contributor

odersky commented Dec 25, 2016

I think this can be fixed with a tweak to the inference rules, which was missing so far in dotty.

smarter added a commit to dotty-staging/dotty that referenced this issue Dec 26, 2016
Given:
  val f: Foo = new Foo
  def wrap2a[A, W <: Wrapper[A]](host: A)(implicit w: W): W = ???
  wrap2a(f)

We need to instantiate `A` before doing the implicit search for `w`
because it was constrained by the first parameter list. This was not
done before because we did not traverse the constraint bounds of an
uninstantiated type variable.
@odersky odersky assigned smarter and unassigned odersky Feb 1, 2017
@odersky odersky closed this as completed in 3966b08 Feb 2, 2018
odersky added a commit that referenced this issue Feb 2, 2018
Fix #1857: Allow lower bounds to influence implicit search
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