diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java index 73e1590e295..9e5133c8215 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java @@ -675,6 +675,7 @@ public void resolveReceiver() { this.receiver.qualifyingName = null; } + resolvedReceiverType = this.scope.environment().getShallowUnannotatedType(resolvedReceiverType); if (TypeBinding.notEquals(enclosingReceiver, resolvedReceiverType)) { this.scope.problemReporter().illegalTypeForExplicitThis(this.receiver, enclosingReceiver); } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java index 853d782c231..8fd4a674e12 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java @@ -2451,6 +2451,19 @@ public void addResolutionListener(IQualifiedTypeResolutionListener resolutionLis public TypeBinding getUnannotatedType(TypeBinding typeBinding) { return this.typeSystem.getUnannotatedType(typeBinding); } +public TypeBinding getShallowUnannotatedType(TypeBinding typeBinding) { + if (typeBinding instanceof ReferenceBinding ref && ref.hasTypeAnnotations()) { + TypeBinding original = ref.original(); + if (ref instanceof ParameterizedTypeBinding ptb && ptb.arguments != null && original instanceof ReferenceBinding originalRef) { + for (TypeBinding arg : ptb.arguments) { + if (arg.hasTypeAnnotations()) + return createParameterizedType(originalRef, ptb.arguments, ptb.enclosingType); + } + } + return this.typeSystem.getUnannotatedType(typeBinding); + } + return typeBinding; +} // Given a type, return all its variously annotated versions. public TypeBinding[] getAnnotatedTypes(TypeBinding type) { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java index 9c39cd53a41..4e8bc45c199 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java @@ -19812,4 +19812,27 @@ void expire() {} """; runner.runNegativeTest(); } + +public void testGH4494() throws Exception { + runConformTest(new String[] { + "AnnotatedExplicitReceiverError.java", + """ + import java.lang.annotation.ElementType; + import java.lang.annotation.Target; + + public class AnnotatedExplicitReceiverError { + @Target({ ElementType.TYPE_USE}) + private static @interface A { } + + @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER }) + private static @interface F { } + + static class P<@A T> { + public void explicitReceiver(@F P this) { // error here + } + } + } + """ + }); +} }