-
Notifications
You must be signed in to change notification settings - Fork 1.1k
given instance parameters cannot appear in the type of a member of the instance #8397
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
Comments
@smarter implicit def foo(implicit x: Int): { type T = x.type } = new {
type T = x.type
} |
Yes, but then |
@neko-kai Unfortunately, "lifting out" the necessary type constraints into a refinement is a rats nest of complexity. At least if you look at the problem in general with all its corner cases. |
@odersky This type is currently inferred automatically if you omit the signature, so it appears the mechanisms are already present, although I may not be aware of more complex cases |
I'm not sure I follow, available as a given in what context ? |
@smarter As a field of the class. OK, maybe that's not so much of a problem since the class would usually not be referred to by name. But then there's the issue that we'd create a field that's typically not used at runtime. |
@neko-kai We'd have to try out the anonymous class encoding to see whether it would work in all cases. |
@odersky |
@neko-kai The anonymous class encoding infers the right type only if there are no parents at all. Once you put in the EDIT That's for Dotty. In So, one question is: should we go back and infer type and value refinements for the types of anonymous classes? So far we did not, because inferring type refinements is messy, and value refinements require reflection at runtime. We have accepted that we need value refinements to support Chisel and there was an idea to do this if the anonymous class inherits from |
If the given parameter is used in any method of the given instance, then we need a field anyway. So this is only sub-optimal when the parameter is used purely as a witness (in which case ideally you'd want the ability to mark it
Good point. Instead of making it public, we could make it protected, Dotty would still be OK with having it appear in the type of a public member. |
@smarter Good idea. Let's try with protected. |
Fix #8397: Make context parameters of given instances protected
Scala 2 can avoid reflection for refinements that are 'local enough', e.g. def makeResource[A](acquire: => A)(release: A => Unit): Unit = makeResource(acquire)(release)
makeResource {
object x {
def close(): Unit = ()
}
x
}(_.close()) // no reflective access, even though there's no expressible type parameter for makeResource This ability could be extended to public refinements coming from anonymous instances (i.e. the type stores the anonymous class also). Theoretically. I understand that it would probably be nonviable due to binary compatibility. To be honest, what I'm irked about is the sudden and inconsistent namespace polution from given instances. This causes an error: case class A[B](b: B)
given A[B: Show] as Show[A] {
def show(a: A) = "A(${Show(B)})"
}
// A is already defined as class A But this doesn't: case class A[B](b: B)
given A as Show[A[Int]] Because only a parameterized given takes up two public names, the rest of the givens only take up a value name! |
minimized code
Compilation output
expectation
This could compile if
x
was desugared to a public val infoo
.The text was updated successfully, but these errors were encountered: