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

Disallow dependent implicit methods. #1467

Closed
wants to merge 3 commits into from

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Aug 23, 2016

The following scala script shows that scalac does not support them very well either:

scala> trait T { type X; val x: X }
defined trait T

scala> implicit def f(x: T): x.X = x.x
warning: there was one feature warning; re-run with -feature for details
f: (x: T)x.X

scala> val t = new T { type X = String; val x = "" }
t: T{type X = String} = $anon$1@496bc455

scala> val x: String = t
<console>:14: error: type mismatch;
 found   : T{type X = String}
 required: String
       val x: String = t
                       ^

scala> val x: String = f(t)
x: String = ""

Instead of doing a half-assed job, we should disallow such implicits completely.
They are still supported under -language:Scala2, but type inference is less good
than in scalac (i.e. we fail to find the right implicit more often).

The following scala script shows that scalac does not support them very well either:

    scala> trait T { type X; val x: X }
    defined trait T

    scala> implicit def f(x: T): x.X = x.x
    warning: there was one feature warning; re-run with -feature for details
    f: (x: T)x.X

    scala> val t = new T { type X = String; val x = "" }
    t: T{type X = String} = $anon$1@496bc455

    scala> val x: String = t
    <console>:14: error: type mismatch;
     found   : T{type X = String}
     required: String
           val x: String = t
                           ^

    scala> val x: String = f(t)
    x: String = ""

Instead of doing a half-assed job, we should disallow such implicits completely.
They are still supported under -language:Scala2, but type inference is less good
than in scalac (i.e. we fail to find the right implicit more often).
@smarter
Copy link
Member

smarter commented Aug 25, 2016

Note that this seems to actually be used in practice: https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/poly.scala#L248
@odersky Do you see any fundamental reason that would prevent us from supporting this correctly or is it just a matter of spending enough time to get it right?

@smarter
Copy link
Member

smarter commented Aug 25, 2016

The change itself LGTM

@odersky
Copy link
Contributor Author

odersky commented Aug 26, 2016

Good point about shapeless. I think we might be able to accept this
usecase. Interestingly,
implicit results depending on implicit parameters is OK, but implicit
results depending on normal
parameters is not.

On Fri, Aug 26, 2016 at 1:39 AM, Guillaume Martres <notifications@github.com

wrote:

The change itself LGTM


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#1467 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAwlVpnMrW5JQST6lFXv0Batsc0i5DTWks5qjiekgaJpZM4JrKca
.
{"api_version":"1.0","publisher":{"api_key":"
05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":
{"external_key":"github/lampepfl/dotty","title":"
lampepfl/dotty","subtitle":"GitHub repository","main_image_url":"
https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-
11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://
cloud.githubusercontent.com/assets/143418/15842166/
7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in
GitHub","url":"https://github.com/lampepfl/dotty"}},"
updates":{"snippets":[{"icon":"PERSON","message":"@smarter in #1467: The
change itself LGTM"}],"action":{"name":"View Pull Request","url":"https://
github.com//pull/1467#issuecomment-242579908"}}}

Prof. Martin Odersky
LAMP/IC, EPFL

@retronym
Copy link
Member

@odersky Our discussion in SI-5070 might be relevant here.

Allow result types of implicit methods to depend on implicit parameters.
 - Add neg test against disallowed implicits
 - Add pos test for t5070
 - Reinstantiate the depmeth oopsla tests in pending; they do not work for other reasons.
@smarter
Copy link
Member

smarter commented Aug 26, 2016

Interestingly, implicit results depending on implicit parameters is OK, but implicit results depending on normal parameters is not.

Could you explain why?

@odersky
Copy link
Contributor Author

odersky commented Aug 26, 2016

I checked and in actually cannot find an example which we cannot do. The case where scalac fails actually compiles in Dotty, as does the example in SI-5070. The dependent method tests in pending fail for other reasons it seems. So I am closing and will integrate the new tests in another PR.

@odersky odersky closed this Aug 26, 2016
@smarter
Copy link
Member

smarter commented Aug 26, 2016

It seems to me that you could always replace a non-implicit parameter by an implicit one with some trickery:

trait T {
  type X
  val x: X
}

trait Box {
  type Elem
}
object Box {
  implicit def box[T]: Box { type Elem = T } = new Box { type Elem = T }
}

object Test {
  val t = new T { type X = String; val x = "" }

  def test: Unit = {
    implicit def f(x: T)(implicit box: Box { type Elem = x.type }): box.Elem#X = x.x

    val z: String = t // OK
  }
}

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

Successfully merging this pull request may close these issues.

3 participants