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

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java (+161 lines)
Lines 39346-39349 Link Here
39346
		},
39346
		},
39347
		"");
39347
		"");
39348
}
39348
}
39349
public void test1179() {
39350
	this.runNegativeTest(
39351
		new String[] {
39352
			"X.java",
39353
			"public class X<T extends Object&V, V> {}\n" + 
39354
			"\n", // =================
39355
		},
39356
		"----------\n" + 
39357
		"1. ERROR in X.java (at line 1)\n" + 
39358
		"	public class X<T extends Object&V, V> {}\n" + 
39359
		"	                                ^\n" + 
39360
		"The type V is not an interface; it cannot be specified as a bounded parameter\n" + 
39361
		"----------\n");
39362
}
39363
public void test1180() {
39364
	this.runNegativeTest(
39365
		new String[] {
39366
			"X.java",
39367
			"public class X {\n" + 
39368
			"	public static <S, T extends Comparable<S>, R extends S & T> R max1(T arg1, S arg2) {\n" + 
39369
			"		return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + 
39370
			"	}\n" + 
39371
			"\n" + 
39372
			"	public static <T extends Comparable<S>, S, R extends S & Comparable<S>> R max2(T arg1, S arg2) {\n" + 
39373
			"		return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + 
39374
			"	}\n" + 
39375
			"\n" + 
39376
			"	public static <T extends Comparable<S>, S, R extends Comparable<S>> R max3(T arg1, S arg2) {\n" + 
39377
			"		return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + 
39378
			"	}\n" + 
39379
			"\n" + 
39380
			"	public static void main(String[] args) {\n" + 
39381
			"	}\n" + 
39382
			"}\n", // =================
39383
		},
39384
		"----------\n" + 
39385
		"1. ERROR in X.java (at line 2)\n" + 
39386
		"	public static <S, T extends Comparable<S>, R extends S & T> R max1(T arg1, S arg2) {\n" + 
39387
		"	                                                         ^\n" + 
39388
		"Cannot specify any additional bound T when first bound is a type parameter\n" + 
39389
		"----------\n" + 
39390
		"2. WARNING in X.java (at line 3)\n" + 
39391
		"	return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + 
39392
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
39393
		"Type safety: Unchecked cast from Object to R\n" + 
39394
		"----------\n" + 
39395
		"3. ERROR in X.java (at line 6)\n" + 
39396
		"	public static <T extends Comparable<S>, S, R extends S & Comparable<S>> R max2(T arg1, S arg2) {\n" + 
39397
		"	                                                         ^^^^^^^^^^\n" + 
39398
		"Cannot specify any additional bound Comparable<S> when first bound is a type parameter\n" + 
39399
		"----------\n" + 
39400
		"4. WARNING in X.java (at line 7)\n" + 
39401
		"	return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + 
39402
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
39403
		"Type safety: Unchecked cast from Object to R\n" + 
39404
		"----------\n" + 
39405
		"5. WARNING in X.java (at line 11)\n" + 
39406
		"	return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + 
39407
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
39408
		"Type safety: Unchecked cast from Object to R\n" + 
39409
		"----------\n");
39410
}
39411
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=204534
39412
public void _test1181() {
39413
	this.runNegativeTest(
39414
		new String[] {
39415
			"X.java",
39416
			"public class X {\n" + 
39417
			"	public static <S, T extends Comparable<S>, R extends S & T> R max(T arg1, S arg2) {\n" + 
39418
			"		return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + 
39419
			"	}\n" + 
39420
			"\n" + 
39421
			"	public static <T extends Comparable<S>, S, R extends S & Comparable<S>> R max(T arg1, S arg2) {\n" + 
39422
			"		return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + 
39423
			"	}\n" + 
39424
			"\n" + 
39425
			"	public static <T extends Comparable<S>, S, R extends Comparable<S>> R max(T arg1, S arg2) {\n" + 
39426
			"		return (R) ((arg1.compareTo(arg2) > 0) ? arg1 : arg2);\n" + 
39427
			"	}\n" + 
39428
			"\n" + 
39429
			"	public static void main(String[] args) {\n" + 
39430
			"	}\n" + 
39431
			"}\n", // =================
39432
		},
39433
		"should not see errors like: R cannot be resolved to a type");
39434
}
39435
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=204536
39436
public void test1182() {
39437
	this.runNegativeTest(
39438
		new String[] {
39439
			"X.java",
39440
			"public class X<T extends Zork & Zork & Object> {\n" + 
39441
			"}\n", // =================
39442
		},
39443
		"----------\n" + 
39444
		"1. ERROR in X.java (at line 1)\n" + 
39445
		"	public class X<T extends Zork & Zork & Object> {\n" + 
39446
		"	                         ^^^^\n" + 
39447
		"Zork cannot be resolved to a type\n" + 
39448
		"----------\n" + 
39449
		"2. ERROR in X.java (at line 1)\n" + 
39450
		"	public class X<T extends Zork & Zork & Object> {\n" + 
39451
		"	                                ^^^^\n" + 
39452
		"Zork cannot be resolved to a type\n" + 
39453
		"----------\n" + 
39454
		"3. ERROR in X.java (at line 1)\n" + 
39455
		"	public class X<T extends Zork & Zork & Object> {\n" + 
39456
		"	                                       ^^^^^^\n" + 
39457
		"The type Object is not an interface; it cannot be specified as a bounded parameter\n" + 
39458
		"----------\n");
39459
}
39460
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=204536 - variation
39461
public void test1183() {
39462
	this.runNegativeTest(
39463
		new String[] {
39464
			"X.java",
39465
			"public class X<T extends Zork & Runnable> {\n" + 
39466
			"	void foo(T t) {\n" + 
39467
			"		t.run();\n" + 
39468
			"	}\n" + 
39469
			"	\n" + 
39470
			"}\n", // =================
39471
		},
39472
		"----------\n" + 
39473
		"1. ERROR in X.java (at line 1)\n" + 
39474
		"	public class X<T extends Zork & Runnable> {\n" + 
39475
		"	                         ^^^^\n" + 
39476
		"Zork cannot be resolved to a type\n" + 
39477
		"----------\n");
39478
}
39479
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=204536 - variation
39480
public void test1184() {
39481
	// check that unresolved first bound got erased into Object (and not Runnable)
39482
	this.runNegativeTest(
39483
		new String[] {
39484
			"X.java",
39485
			"public class X<T extends Zork & Runnable> {\n" + 
39486
			"	T get() { return null; }\n" +
39487
			"	void foo(X x) {\n" + 
39488
			"		Runnable r = x.get();\n" + 
39489
			"	}\n" + 
39490
			"	\n" + 
39491
			"}\n", // =================
39492
		},
39493
		"----------\n" + 
39494
		"1. ERROR in X.java (at line 1)\n" + 
39495
		"	public class X<T extends Zork & Runnable> {\n" + 
39496
		"	                         ^^^^\n" + 
39497
		"Zork cannot be resolved to a type\n" + 
39498
		"----------\n" + 
39499
		"2. WARNING in X.java (at line 3)\n" + 
39500
		"	void foo(X x) {\n" + 
39501
		"	         ^\n" + 
39502
		"X is a raw type. References to generic type X<T> should be parameterized\n" + 
39503
		"----------\n" + 
39504
		"3. ERROR in X.java (at line 4)\n" + 
39505
		"	Runnable r = x.get();\n" + 
39506
		"	             ^^^^^^^\n" + 
39507
		"Type mismatch: cannot convert from Object to Runnable\n" + 
39508
		"----------\n");
39509
}
39349
}
39510
}
(-)buildnotes_jdt-core.html (+1 lines)
Lines 53-58 Link Here
53
53
54
<h3>Problem Reports Fixed</h3>
54
<h3>Problem Reports Fixed</h3>
55
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154071">154071</a>
55
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154071">154071</a>
56
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154071">154071</a>
56
No notification of change if a project is added or removed from a container
57
No notification of change if a project is added or removed from a container
57
58
58
<a name="v_815"></a>
59
<a name="v_815"></a>
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java (-67 / +84 lines)
Lines 447-457 Link Here
447
		return null; // incompatible
447
		return null; // incompatible
448
	}
448
	}
449
	
449
	
450
	/**
451
	 * Connect type variable supertypes, and returns true if no problem was detected
452
	 * @param typeParameters
453
	 * @param checkForErasedCandidateCollisions
454
	 */
450
	protected boolean connectTypeVariables(TypeParameter[] typeParameters, boolean checkForErasedCandidateCollisions) {
455
	protected boolean connectTypeVariables(TypeParameter[] typeParameters, boolean checkForErasedCandidateCollisions) {
451
		if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) return true;
456
		if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) return true;
452
		boolean noProblems = true;
453
		Map invocations = new HashMap(2);
457
		Map invocations = new HashMap(2);
454
		nextVariable : for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) {
458
		boolean noProblems = true;
459
		nextVariable: for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) {
455
			TypeParameter typeParameter = typeParameters[i];
460
			TypeParameter typeParameter = typeParameters[i];
456
			TypeVariableBinding typeVariable = typeParameter.binding;
461
			TypeVariableBinding typeVariable = typeParameter.binding;
457
			if (typeVariable == null) return false;
462
			if (typeVariable == null) return false;
Lines 464-556 Link Here
464
			TypeReference typeRef = typeParameter.type;
469
			TypeReference typeRef = typeParameter.type;
465
			if (typeRef == null)
470
			if (typeRef == null)
466
				continue nextVariable;
471
				continue nextVariable;
472
			boolean isFirstBoundTypeVariable = false;
467
			TypeBinding superType = this.kind == METHOD_SCOPE
473
			TypeBinding superType = this.kind == METHOD_SCOPE
468
				? typeRef.resolveType((BlockScope)this, false/*no bound check*/)
474
				? typeRef.resolveType((BlockScope)this, false/*no bound check*/)
469
				: typeRef.resolveType((ClassScope)this);
475
				: typeRef.resolveType((ClassScope)this);
470
			if (superType == null) {
476
			if (superType == null) {
471
				typeVariable.tagBits |= TagBits.HierarchyHasProblems;
477
				typeVariable.tagBits |= TagBits.HierarchyHasProblems;
472
				noProblems = false;
473
				continue nextVariable;
474
			}
475
			typeRef.resolvedType = superType; // hold onto the problem type
476
			if (superType.isArrayType()) {
477
				problemReporter().boundCannotBeArray(typeRef, superType);
478
				continue nextVariable;
479
			}
480
			boolean isTypeVariableFirstBound =  superType.isTypeVariable();
481
			if (isTypeVariableFirstBound) {
482
				TypeVariableBinding varSuperType = (TypeVariableBinding) superType;
483
				if (varSuperType.rank >= typeVariable.rank && varSuperType.declaringElement == typeVariable.declaringElement) {
484
					problemReporter().forwardTypeVariableReference(typeParameter, varSuperType);
485
					typeVariable.tagBits |= TagBits.HierarchyHasProblems;
486
					noProblems = false;
487
					continue nextVariable;
488
				}
489
			}
490
			ReferenceBinding superRefType = (ReferenceBinding) superType;
491
			if (superRefType.isFinal())
492
				problemReporter().finalVariableBound(typeVariable, typeRef);
493
			if (!superType.isInterface()) {
494
				typeVariable.superclass = superRefType;
495
			} else {
478
			} else {
496
				typeVariable.superInterfaces = new ReferenceBinding[] {superRefType};
479
				typeRef.resolvedType = superType; // hold onto the problem type
480
				firstBound: {
481
					switch (superType.kind()) {
482
						case Binding.ARRAY_TYPE :
483
							problemReporter().boundCannotBeArray(typeRef, superType);
484
							typeVariable.tagBits |= TagBits.HierarchyHasProblems;
485
							break firstBound; // do not keep first bound
486
						case Binding.TYPE_PARAMETER :
487
							isFirstBoundTypeVariable = true;
488
							TypeVariableBinding varSuperType = (TypeVariableBinding) superType;
489
							if (varSuperType.rank >= typeVariable.rank && varSuperType.declaringElement == typeVariable.declaringElement) {
490
								problemReporter().forwardTypeVariableReference(typeParameter, varSuperType);
491
								typeVariable.tagBits |= TagBits.HierarchyHasProblems;
492
								break firstBound; // do not keep first bound
493
							}
494
							break;
495
						default :
496
							if (((ReferenceBinding) superType).isFinal()) {
497
								problemReporter().finalVariableBound(typeVariable, typeRef);
498
							}
499
							break;
500
					}
501
					ReferenceBinding superRefType = (ReferenceBinding) superType;
502
					if (!superType.isInterface()) {
503
						typeVariable.superclass = superRefType;
504
					} else {
505
						typeVariable.superInterfaces = new ReferenceBinding[] {superRefType};
506
					}
507
					typeVariable.firstBound = superRefType; // first bound used to compute erasure
508
				}
497
			}
509
			}
498
			typeVariable.firstBound = superRefType; // first bound used to compute erasure
499
			TypeReference[] boundRefs = typeParameter.bounds;
510
			TypeReference[] boundRefs = typeParameter.bounds;
500
			if (boundRefs != null) {
511
			if (boundRefs != null) {
501
				for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) {
512
				nextBound: for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) {
502
					typeRef = boundRefs[j];
513
					typeRef = boundRefs[j];
503
					superType = this.kind == METHOD_SCOPE
514
					superType = this.kind == METHOD_SCOPE
504
						? typeRef.resolveType((BlockScope)this, false)
515
						? typeRef.resolveType((BlockScope)this, false)
505
						: typeRef.resolveType((ClassScope)this);
516
						: typeRef.resolveType((ClassScope)this);
506
					if (superType == null) {
517
					if (superType == null) {
507
						typeVariable.tagBits |= TagBits.HierarchyHasProblems;
518
						typeVariable.tagBits |= TagBits.HierarchyHasProblems;
508
						noProblems = false;
519
						continue nextBound;
509
						continue nextVariable;
520
					} else {
510
					}
521
						typeRef.resolvedType = superType; // hold onto the problem type
511
					typeRef.resolvedType = superType; // hold onto the problem type
522
						boolean didAlreadyComplain = false;
512
					if (isTypeVariableFirstBound && j == 0) {
523
						if (isFirstBoundTypeVariable && j == 0) {
513
						problemReporter().noAdditionalBoundAfterTypeVariable(typeRef);
524
							problemReporter().noAdditionalBoundAfterTypeVariable(typeRef);
514
					}
515
					if (superType.isArrayType()) {
516
						problemReporter().boundCannotBeArray(typeRef, superType);
517
						continue nextVariable;
518
					}
519
					superRefType = (ReferenceBinding) superType;
520
					if (!superType.isInterface()) {
521
						problemReporter().boundMustBeAnInterface(typeRef, superType);
522
						typeVariable.tagBits |= TagBits.HierarchyHasProblems;
523
						noProblems = false;
524
						continue nextVariable;
525
					}
526
					// check against superclass
527
					if (checkForErasedCandidateCollisions && typeVariable.firstBound == typeVariable.superclass) {
528
						if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef)) {
529
							noProblems = false;
530
							continue nextVariable;
531
						}
532
					}
533
					// check against superinterfaces
534
					for (int index = typeVariable.superInterfaces.length; --index >= 0;) {
535
						ReferenceBinding previousInterface = typeVariable.superInterfaces[index];
536
						if (previousInterface == superRefType) {
537
							problemReporter().duplicateBounds(typeRef, superType);
538
							typeVariable.tagBits |= TagBits.HierarchyHasProblems;
525
							typeVariable.tagBits |= TagBits.HierarchyHasProblems;
539
							noProblems = false;
526
							didAlreadyComplain = true;
540
							continue nextVariable;
527
							//continue nextBound; - keep these bounds to minimize secondary errors
528
						} else if (superType.isArrayType()) {
529
							if (!didAlreadyComplain) {
530
								problemReporter().boundCannotBeArray(typeRef, superType);
531
								typeVariable.tagBits |= TagBits.HierarchyHasProblems;
532
							}
533
							continue nextBound;
534
						} else {
535
							if (!superType.isInterface()) {
536
								if (!didAlreadyComplain) {
537
									problemReporter().boundMustBeAnInterface(typeRef, superType);
538
									typeVariable.tagBits |= TagBits.HierarchyHasProblems;
539
								}
540
								continue nextBound;
541
							}
541
						}
542
						}
542
						if (checkForErasedCandidateCollisions) {
543
						// check against superclass
543
							if (hasErasedCandidatesCollisions(superType, previousInterface, invocations, typeVariable, typeRef)) {
544
						if (checkForErasedCandidateCollisions && typeVariable.firstBound == typeVariable.superclass) {
544
								noProblems = false;
545
							if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef)) {
545
								continue nextVariable;
546
								continue nextBound;
547
							}
548
						}
549
						// check against superinterfaces
550
						ReferenceBinding superRefType = (ReferenceBinding) superType;
551
						for (int index = typeVariable.superInterfaces.length; --index >= 0;) {
552
							ReferenceBinding previousInterface = typeVariable.superInterfaces[index];
553
							if (previousInterface == superRefType) {
554
								problemReporter().duplicateBounds(typeRef, superType);
555
								typeVariable.tagBits |= TagBits.HierarchyHasProblems;
556
								continue nextBound;
557
							}
558
							if (checkForErasedCandidateCollisions) {
559
								if (hasErasedCandidatesCollisions(superType, previousInterface, invocations, typeVariable, typeRef)) {
560
									continue nextBound;
561
								}
546
							}
562
							}
547
						}
563
						}
564
						int size = typeVariable.superInterfaces.length;
565
						System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size);
566
						typeVariable.superInterfaces[size] = superRefType;
548
					}
567
					}
549
					int size = typeVariable.superInterfaces.length;
550
					System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size);
551
					typeVariable.superInterfaces[size] = superRefType;
552
				}
568
				}
553
			}
569
			}
570
			noProblems &= (typeVariable.tagBits & TagBits.HierarchyHasProblems) == 0;
554
		}
571
		}
555
		return noProblems;
572
		return noProblems;
556
	}
573
	}

Return to bug 204536