diff --git a/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java new file mode 100644 index 000000000000..5728c2f2d409 --- /dev/null +++ b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.java @@ -0,0 +1,20 @@ +/* + * @test + * @summary Test case for method receiver type in error message. If it is a non-raw type, it should be printed as such. + * + * @compile/fail/ref=MethodReceiverTypeErrorMessageTest.out -XDrawDiagnostics -processor org.checkerframework.checker.nullness.NullnessChecker MethodReceiverTypeErrorMessageTest.java + */ +public class MethodReceiverTypeErrorMessageTest { + + MethodReceiverTypeErrorMessageTest() { + foo(); + } + + void foo() {} + + static class StringSpecialization extends MethodReceiverTypeErrorMessageTest { + StringSpecialization() { + foo(); + } + } +} diff --git a/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out new file mode 100644 index 000000000000..6c2c97e29eac --- /dev/null +++ b/checker/jtreg/nullness/MethodReceiverTypeErrorMessageTest.out @@ -0,0 +1,7 @@ +MethodReceiverTypeErrorMessageTest.java:10:12: compiler.err.proc.messager: [method.invocation.invalid] call to foo() not allowed on the given receiver. +found : @UnderInitialization(MethodReceiverTypeErrorMessageTest.class) MethodReceiverTypeErrorMessageTest +required: @Initialized MethodReceiverTypeErrorMessageTest +MethodReceiverTypeErrorMessageTest.java:17:16: compiler.err.proc.messager: [method.invocation.invalid] call to foo() not allowed on the given receiver. +found : @UnderInitialization(MethodReceiverTypeErrorMessageTest.StringSpecialization.class) StringSpecialization +required: @Initialized MethodReceiverTypeErrorMessageTest<@Initialized String> +2 errors diff --git a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java index 4bdeda3ca0b8..c9a256fa866f 100644 --- a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java +++ b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java @@ -3983,7 +3983,8 @@ protected void checkMethodInvocability( return; } - AnnotatedTypeMirror erasedMethodReceiver = method.getReceiverType().getErased(); + AnnotatedTypeMirror methodReceiver = method.getReceiverType(); + AnnotatedTypeMirror erasedMethodReceiver = methodReceiver.getErased(); AnnotatedTypeMirror erasedTreeReceiver = erasedMethodReceiver.shallowCopy(false); AnnotatedTypeMirror treeReceiver = atypeFactory.getReceiverType(tree); @@ -3992,13 +3993,13 @@ protected void checkMethodInvocability( if (!skipReceiverSubtypeCheck(tree, erasedMethodReceiver, treeReceiver)) { // The diagnostic can be a bit misleading because the check is of the receiver but // `tree` is the entire method invocation (where the receiver might be implicit). - commonAssignmentCheckStartDiagnostic(erasedMethodReceiver, erasedTreeReceiver, tree); + commonAssignmentCheckStartDiagnostic(methodReceiver, erasedTreeReceiver, tree); boolean success = typeHierarchy.isSubtype(erasedTreeReceiver, erasedMethodReceiver); commonAssignmentCheckEndDiagnostic( - success, null, erasedMethodReceiver, erasedTreeReceiver, tree); + success, null, methodReceiver, erasedTreeReceiver, tree); if (!success) { // Don't report the erased types because they show up with '' as type args. - reportMethodInvocabilityError(tree, treeReceiver, method.getReceiverType()); + reportMethodInvocabilityError(tree, treeReceiver, methodReceiver); } } }