-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Typing of the method ignores knowledge that could be collected from type bounds on method targs #592
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
ping @odersky @adriaanm @smarter @samuelgruetter @namin Handling this case seems to account for 90% of problems with specialization that we have seen so far. |
…ethods. The way how this fix is structures, is that if 592 ever gets fixed, no casts will be inserted.
So in the body of
The problem is that the above implication does not hold, because Note: This is (at least slightly) related to #525, where we see that dotty checks that the lower bound of a type parameter always is a subtype of the upper bound. |
@samuelgruetter , I had an error in my original text. Please see the update.
|
Do you want to the return type to be Return type
(but not in dotty because of #525). |
It's not only about return type of the method itself, that's about any expected type in general, be it type of val defined in method, or be it argument of a another method called in this one. |
And yes, in this example, for the body of method to typecheck, I need it to be able to infer that |
Do you create a new specialized trait
|
This does not matter. Ok, let me clear this up step-by-step. trait A[+T] {
def foo[@specialized(Int) B >: T]: A[B] = {
def id[X](t: X) = t
id[A[B]](this)
val s: A[B] = this
s
}
} specialization will duplicate this method, creating: trait A[+T] {
// specialization for integers.
// you get it by replacing all references to `B` by `Int` in types.
def foo_sp_Int[B >: T <: Int]: A[Int] = {
def id[X](t: X) = t
id[A[Int]](this) // does not typecheck, this is not a subtype of A[Int]
val s: A[Int] = this // does not typecheck, this is not a subtype of A[Int]
s // does not typecheck, this is not a subtype of A[Int]
}
// generic version, no changes
def foo[B >: T]: A[B] = {
def id[X](t: X) = t
id[A[B]](this)
val s: A[B] = this
s
}
} |
I see... So as a Scala user, you would use an ascription to give the compiler a hint: Btw thanks for editing |
Type ascription does not work here, as it is typechecked, and typechecking it will fail. Type casts work, but they are spliced everywhere in more-or-less compicated code. |
We have |
Ok, I get it now. It could indeed work. |
How about dropping the definition of B entirely and putting a constraint in the context for the method body? Can dotty type check modulo constraints (like [HM[X]](Type Inference with Constrained Types - LAMP | EPFL))?
|
@DarkDimius, what you need is the ability to inject the information that As an alternative, you can do the shallow transformation, like I do in miniboxing, and you wouldn't run into this problem (e.g. |
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
…ethods. The way this fix is structured ensures that if scala#592 ever gets fixed, no casts will be inserted.
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
…ethods. The way this fix is structured ensures that if scala#592 ever gets fixed, no casts will be inserted.
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
…ethods. The way this fix is structured ensures that if scala#592 ever gets fixed, no casts will be inserted.
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
…ethods. The way this fix is structured ensures that if scala#592 ever gets fixed, no casts will be inserted.
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
…ethods. The way this fix is structured ensures that if scala#592 ever gets fixed, no casts will be inserted.
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
…ethods. The way this fix is structured ensures that if scala#592 ever gets fixed, no casts will be inserted.
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
…ethods. The way this fix is structured ensures that if scala#592 ever gets fixed, no casts will be inserted.
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
…ethods. The way this fix is structured ensures that if scala#592 ever gets fixed, no casts will be inserted.
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
An issue occurs when trying to specialize certain methods when relying on typer only - this is described by scala#592 , and occured in test `this_specialization`. # with '#' will be ignored, and an empty message aborts the commit.
@AleksanderBG It seems to me this is related to GADT narrowing. Is there a way to generalize and possibly support this use case? |
@liufengyun looking at the comments on the issue, maybe. The fundamental problem I'm seeing is that we only allow adding GADT constraints to type parameters of functions, and all examples in the issue would want to add them to either type members or type parameters of classes, either of which I'd say is non-trivial to soundly allow. |
As in order to call method
foo
one needs to verify type bounds, it seems safe for me to assumeT2 <:< T1
in the body of the methodThis is needed for some compiler rewritings to be type-safe. Eg, specialization of a
will yield
Without typer knowing that
Foo$A
is subtype ofInt
in this example, specialization needs to insert casts.Unfortunately, for the scheme to be complete, specialization needs to insert casts in every place where we have a source of expected type: arguments of methods, vals, defs. Otherwise the tree does not typecheck.
The text was updated successfully, but these errors were encountered: