-
Notifications
You must be signed in to change notification settings - Fork 78
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
Assignability of raw and parameterized types for type variables with multiple bounds (CDI-440) #682
Comments
You're right that the TCK test seems to cover exactly this and has been part of the testsuite since around the time of the CDI JIRA issue (May/June 2014). I also agree that this functionality makes sense. My guess would be that the wording change was simply forgotten back then and injections like these are probably pretty rare so it didn't really surface again. I'd consider it a clarification and add it to the next release unless there are objections OFC. The only issue I have with this is that I am not sure how to word this so that this especially hard-to-read-and-understand section of the spec doesn't get even worse. |
I can try but it will take a while because I am not immediately smart enough to understand the replacement. Additionally, there are many problems with the terminology in that section and I don't want to make the terminology misuse even worse. So should I:
…? For arbitrary examples, the whole section uses "parameter" when it probably means "argument"; "raw type" appears to actually mean "non-generic or raw type", terms like "actual type" are undefined except in comments in closed bugs, "match" is undefined, and so on. Maybe a larger PR is in order that attempts to preserve the exact current meaning in the spec but that uses proper terminology? Maybe it would be huge? Maybe it wouldn't be so bad? I don't know. |
Personally I don't have that much of an issue with the incorrect terminology but I guess I might just be used to it over the years :) Let's see what others think. Cc @Ladicek FTR as far as huge PRs go, that's not an issue as we are now talking 4.1 which is next bigger release (EE 11), so changes like that are not blocking in any way. |
I have noticed some of these inaccuracies myself (type parameter vs type argument is the most obvious one), but haven't been brave enough to do something about it :-) In my opinion, one good way to address this is incremental. Address this issue in a single PR. Address the confusion between type parameters and type arguments in another PR. Address the term "actual type" in yet another PR. And so on. |
So (1)? |
I guess what Ladislav says is he isn't against correcting this throughout the spec (nor am I) but we should do that incrementally. For instance, I'd start with a PR that fixes just (1) - that way we have bad terminology but full scope of functionality covered. |
I probably wasn't entirely clear, so let me rephrase. I'm suggesting to fix one thing at a time, but that one thing that is being fixed or improved should ideally be fixed or improved throughout the spec. |
Also, for this particular issue, here's a proposal: Ladicek@7ca846c (I couldn't resist and improved the wording for class types and array types too.) To be fair, I don't really understand the case when the required type parameter is a wildcard and the bean type parameter is a type variable. Specifically, why should the bound(s) of the type variable be assignable to or assignable from the upper bound? That seems pretty weird to me. Considering an injection point of @Inject
List<? extends CharSequence> list; then all these beans would be assignable: @Dependent
class MyBean1<T extends CharSequence> implements List<T> {
}
@Dependent
class MyBean2<T extends String> implements List<T> {
}
@Dependent
class MyBean3<T extends Object> implements List<T> {
} I'm not trying to change that right now, but I'd like to hear anyone's opinion on that. |
Yea, I agree this seems weird. The lower bound bit of text doesn't contain this wording either. |
My perhaps incorrect understanding is that for better or for worse the bean type argument (The fact that "match" is only partially defined I'll leave untouched for now.) From looking at Weld code, the only time covariant assignability does come into play is with multiple type parameter bounds (which is not applicable in your example). So that's here (https://github.com/weld/core/blob/c538ec4f6a1a37a89bc3afa5c59babe6597c01da/impl/src/main/java/org/jboss/weld/resolution/BeanTypeAssignabilityRules.java#L178), but the method addressing your example is here: https://github.com/weld/core/blob/c538ec4f6a1a37a89bc3afa5c59babe6597c01da/impl/src/main/java/org/jboss/weld/resolution/BeanTypeAssignabilityRules.java#L162. Again, it's hard to understand all this so I might be making a mistake. |
Hm, I think you might be mixing up a few things. The spec wording operating on the bounds of the wildcard and bean type variable and allowing you to compare assignability both, from and to the upper bound effectively means that Indeed, if you try Ladislav's example in Weld, you'll see that all three beans are considered valid. I've taken a look at the TCKs and found this test.
Which means you will be checking assignability of |
I actually think the word "match" is defined fairly well in the CDI specification, specifically in the paragraph that starts with "The bean has a bean type that matches the required type". The rest of the paragraph describes a relation On the other hand, it is very true that the CDI specification has its own definition of types being "assignable to" one another. It seems to me that this definition sometimes refers to itself, recursively, while other times, it refers to the Java definition. That isn't detailed anywhere, unfortunately, but CDI for example never defines what "assignable from" means and yet the term is used on several places -- it seems clear to me that that is the Java notion of assignability. |
Ah and one more thing I wanted to say: it is unfortunate that the Weld codebase uses the term "match" on so many places, but that shouldn't be used to infer any conclusions about the CDI specification. |
Thought about this a bit and had an idea: Only Dependent beans are allowed to have parameterized types. So when you're trying to evaluate whether a bean with type parameters is valid for a required type, you're asking "is there any value I could use for the type variables that would allow it to be valid here". So with your
Does that sound reasonable? |
That is not exactly true ( Indeed the rule likely only applies to dependent beans, which means that from the type system perspective, it is as if the type variable was substituted for an actual type independently for each injection point. I need to think more about it, but this might be a correct explanation, thanks! |
Hmm, that also opens up door for virtually unlimited set of incorrect types that the list can contain - then again, when dealing with generic types on bean (and hence dependent beans) there is plenty of ways to break the type safety if you want to. |
Ladicek:
So partially defined. manovotn:
I was indeed. Assignability of bounds is indeed covariant, always. |
@ljnelson feel free to propose a PR with changes and we can continue the discussion there. After all, it's easier to talk code/text than hypothetical changes :) |
@ljnelson are you willing to propose a PR for this change? |
Probably not in time for the milestone :) |
I happened to notice that CDI-440 does not seem to have any resolution in the current version of the CDI specification.
Following the rules in the Jira issue, which read:
…I am filing this issue to resurrect CDI-440.
The original issue reads:
A comment indicates that this interpretation would seem to be correct, but it was never adopted.
There is a related issue that indicates that Weld adopted and implemented this unofficial interpretation.
The TCK appears to perhaps enforce this unofficial interpretation as well.
I'm not sure the suggested language is exactly correct, but the spirit of it seems correct.
The text was updated successfully, but these errors were encountered: