Martin poked around this some more and found some interesting bits.
If you want to uncover why it is like this, take a look at:
* CDI-389[1]
* Related email discussion[2]
* Slightly related DS issue[3]
I glanced over it and my understanding is that at some point it was actually written the
other way around (1.1), but then reverted(1.2).
The reason was producer methods - any bean with generics needs to be dependent scoped and
once you have a dependent scoped producer method, then you
can produce different bean for each injection point. E.g. for injection points
List<Integer> and List<String> you can have a singular producer method that
returns List<E>
and it should be able to satisfy both IPs (when you inspect the IP via InjectionPoint
metadata).
But I think you could also easily have a producer that will throw a class cast exception
at runtime...
Matej
_____________________________________________________________________________________
[1]
From: "Matej Novotny" <manovotn(a)redhat.com>
To: "Laird Nelson" <ljnelson(a)gmail.com>
Cc: "weld-dev" <weld-dev(a)lists.jboss.org>
Sent: Tuesday, April 28, 2020 9:21:19 AM
Subject: Re: [weld-dev] Odd type assignability test
----- Original Message -----
> From: "Laird Nelson" <ljnelson(a)gmail.com>
> To: "weld-dev" <weld-dev(a)lists.jboss.org>
> Sent: Monday, April 27, 2020 5:51:54 PM
> Subject: Re: [weld-dev] Odd type assignability test
>
>
> On Mon, Apr 27, 2020 at 5:38 AM Martin Kouba < mkouba(a)redhat.com > wrote:
>
>
> I think that you're right. Foo<E> is basically Foo<E extends Object>
and
> according to the rules String is assignable to Object.
>
> Just to be clear, this test (that I added temporarily to CovariantTypesTest
> and ran just to make sure) fails (as I'd expect):
>
> @Test
> public <E> void testFooStringAssignableFromFooE() {
> Type a = new TypeLiteral<Foo<String>>() {
> }.getType();
> Type b = new TypeLiteral<Foo<E>>() {
> }.getType();
> assertTrue(CovariantTypes.isAssignableFrom(a, b)); // kaboom
> }
>
> But this test (the one under discussion) in BeanTypeAssignabilityRules
> succeeds (obviously or Weld's test suite would be broken):
>
> @Test
> public <E> void testStringFooMatchesVariableFoo() throws Exception {
> Type stringFooType = new TypeLiteral<Foo<String>>() {
> }.getType();
> Type variableFooType = new TypeLiteral<Foo<E>>() {
> }.getType();
> Assert.assertTrue("Foo<String> should match Foo<E>",
> getRules().matches(stringFooType, variableFooType));
> }
>
> So the rules CDI uses to do type matching (represented by
> BeanTypeAssignabilityRules ) are deliberately different from those used by
> JLS (represented by CovariantTypes ), right?
CovariantTypes/InvariantTypes are used by BeanTypeAssignabilityRules.
My understanding was that CDI dictates some rules, few of which are different
or requiring some extra steps compared to pure JLS. That's why during
evaluation you go through BeanTypeAssignabilityRules and whenever applicable
you delegate to Covariant/InvariantTypes.
>
> Best,
> Laird
>
> _______________________________________________
> weld-dev mailing list
> weld-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/weld-dev
_______________________________________________
weld-dev mailing list
weld-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/weld-dev