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?
Best,
Laird