View | Details | Raw Unified | Return to bug 228291 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java (+27 lines)
Lines 43743-43746 Link Here
43743
			"Unnecessary cast from B to Object\n" + 
43743
			"Unnecessary cast from B to Object\n" + 
43744
			"----------\n");
43744
			"----------\n");
43745
}
43745
}
43746
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228291
43747
public void test1315() {
43748
	this.runNegativeTest(
43749
			new String[] {
43750
					"X.java",
43751
					"import java.util.*;\n" + 
43752
					"\n" + 
43753
					"public class X<T> extends Vector<Collection<T>> {\n" + 
43754
					"	private static final long serialVersionUID = 1L;\n" + 
43755
					"	public Vector<T> cast(List<T> in) {\n" + 
43756
					"		return (Vector<T>) in;\n" + 
43757
					"	}\n" + 
43758
					"	public X<T> castSilly(Vector<Collection<T>> in) {\n" + 
43759
					"		return (X<T>) in;\n" + 
43760
					"	}\n" + 
43761
					"	public static void main(String[] args) {\n" + 
43762
					"		Zork z;\n" + 
43763
					"	}\n" + 
43764
					"}\n", // =================
43765
			},
43766
			"----------\n" + 
43767
			"1. ERROR in X.java (at line 12)\n" + 
43768
			"	Zork z;\n" + 
43769
			"	^^^^\n" + 
43770
			"Zork cannot be resolved to a type\n" + 
43771
			"----------\n");
43772
}
43746
}
43773
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java (-31 / +25 lines)
Lines 326-364 Link Here
326
								return true;
326
								return true;
327
							}
327
							}
328
							// [JLS 5.5] S has no subtype X != T, such that |X| == |T|
328
							// [JLS 5.5] S has no subtype X != T, such that |X| == |T|
329
							TypeBinding genericCastType = castType.erasure(); // jump to generic type
329
							// if I2<T,U> extends I1<T>, then cast from I1<T> to I2<T,U> is unchecked
330
							TypeBinding genericMatch = genericCastType.findSuperTypeOriginatingFrom(expressionType);
330
							ParameterizedTypeBinding paramCastType = (ParameterizedTypeBinding) castType;
331
							if (genericMatch == match) {
331
							ParameterizedTypeBinding paramMatch = (ParameterizedTypeBinding) match;
332
							// easy case if less parameters on match
333
							TypeBinding[] castArguments = paramCastType.arguments;
334
							int length = castArguments.length;
335
							if (length > paramMatch.arguments.length) {
332
								this.bits |= ASTNode.UnsafeCast;
336
								this.bits |= ASTNode.UnsafeCast;
333
							} else {
337
							} else if ((paramCastType.tagBits & (TagBits.HasDirectWildcard|TagBits.HasTypeVariable)) != 0) {
334
								// if I2<T,U> extends I1<T>, then cast from I1<T> to I2<T,U> is unchecked
338
								// verify alternate cast type, substituting different type arguments
335
								ParameterizedTypeBinding paramCastType = (ParameterizedTypeBinding) castType;
339
								nextAlternateArgument: for (int i = 0; i < length; i++) {
336
								ParameterizedTypeBinding paramMatch = (ParameterizedTypeBinding) match;
340
									switch (castArguments[i].kind()) {
337
								// easy case if less parameters on match
341
										case Binding.WILDCARD_TYPE :
338
								TypeBinding[] castArguments = paramCastType.arguments;
342
										case Binding.TYPE_PARAMETER :
339
								int length = castArguments.length;
343
											break; // check substituting with other
340
								if (length > paramMatch.arguments.length) {
344
										default:
341
									this.bits |= ASTNode.UnsafeCast;
345
											continue nextAlternateArgument; // no alternative possible
342
								} else if ((paramCastType.tagBits & (TagBits.HasDirectWildcard|TagBits.HasTypeVariable)) != 0) {
346
									}
343
									// verify alternate cast type, substituting different type arguments
347
									TypeBinding[] alternateArguments;
348
									// need to clone for each iteration to avoid env paramtype cache interference
349
									System.arraycopy(paramCastType.arguments, 0, alternateArguments = new TypeBinding[length], 0, length);
350
									alternateArguments[i] = scope.getJavaLangObject();
344
									LookupEnvironment environment = scope.environment();
351
									LookupEnvironment environment = scope.environment();
345
									nextAlternateArgument: for (int i = 0; i < length; i++) {
352
									ParameterizedTypeBinding alternateCastType = environment.createParameterizedType((ReferenceBinding)castType.erasure(), alternateArguments, castType.enclosingType());
346
										switch (castArguments[i].kind()) {
353
									if (alternateCastType.findSuperTypeOriginatingFrom(expressionType) == match) {
347
											case Binding.WILDCARD_TYPE :
354
										this.bits |= ASTNode.UnsafeCast;
348
											case Binding.TYPE_PARAMETER :
355
										break;
349
												break; // check substituting with other
350
											default:
351
												continue nextAlternateArgument; // no alternative possible
352
										}
353
										TypeBinding[] alternateArguments;
354
										// need to clone for each iteration to avoid env paramtype cache interference
355
										System.arraycopy(paramCastType.arguments, 0, alternateArguments = new TypeBinding[length], 0, length);
356
										alternateArguments[i] = scope.getJavaLangObject();
357
										ParameterizedTypeBinding alternateCastType = environment.createParameterizedType((ReferenceBinding)genericCastType, alternateArguments, castType.enclosingType());
358
										if (alternateCastType.findSuperTypeOriginatingFrom(expressionType) == match) {
359
											this.bits |= ASTNode.UnsafeCast;
360
											break;
361
										}
362
									}
356
									}
363
								}
357
								}
364
							}
358
							}

Return to bug 228291