Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ Other improvements and bug fixes:

**Closed issues:**

eisop#433, eisop#792, eisop#863, eisop#1015, eisop#1074, eisop#1801, eisop#1819.
eisop#386, eisop#433, eisop#792, eisop#863, eisop#1015, eisop#1074, eisop#1801, eisop#1819.


Version 3.49.5-eisop1 (April 26, 2026)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ public void viewpointAdaptConstructor(
constructorType.setParameterTypes(unsubstitutedConstructorType.getParameterTypes());
constructorType.setTypeVariables(unsubstitutedConstructorType.getTypeVariables());
constructorType.setReturnType(unsubstitutedConstructorType.getReturnType());
constructorType.computeVarargType();
}

@Override
Expand Down Expand Up @@ -189,6 +190,7 @@ public void viewpointAdaptMethod(
methodType.setReceiverType(unsubstitutedMethodType.getReceiverType());
methodType.setParameterTypes(unsubstitutedMethodType.getParameterTypes());
methodType.setTypeVariables(unsubstitutedMethodType.getTypeVariables());
methodType.computeVarargType();
}

/**
Expand Down
29 changes: 29 additions & 0 deletions framework/tests/viewpointtest/Issue386.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Test case for EISOP issue #386:
// https://github.com/eisop/checker-framework/issues/386
import viewpointtest.quals.*;

public class Issue386 {
public class Inner {
Inner() {}

Inner(@ReceiverDependentQual Object... args) {}
}

public class MethodReceiver {
void method(@ReceiverDependentQual Object... args) {}
}

@SuppressWarnings("cast.unsafe.constructor.invocation")
public void constructorTest(@A Object aObj, @A Object otherAObj, @B Object bObj) {
this.new @A Inner(aObj, otherAObj);
// :: error: (argument.type.incompatible)
Comment thread
aosen-xiong marked this conversation as resolved.
this.new @A Inner(aObj, bObj);
}

public void methodTest(
@A MethodReceiver receiver, @A Object aObj, @A Object otherAObj, @B Object bObj) {
receiver.method(aObj, otherAObj);
// :: error: (argument.type.incompatible)
Comment thread
aosen-xiong marked this conversation as resolved.
receiver.method(aObj, bObj);
}
}
8 changes: 5 additions & 3 deletions framework/tests/viewpointtest/VarargsConstructor.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ void foo() {
void invokeConstructor(@A Object aObj, @B Object bObj, @Top Object topObj) {
@A Object a = new @A VarargsConstructor(aObj);
@B Object b = new @B VarargsConstructor(bObj);
// :: error: (argument.type.incompatible) :: error: (new.class.type.invalid)
// :: error: (argument.type.incompatible) :: error: (new.class.type.invalid) :: error:
// (varargs.type.incompatible)
@Top Object top = new @Top VarargsConstructor(topObj);
// :: error: (argument.type.incompatible)
new @A VarargsConstructor(bObj);
Expand All @@ -30,7 +31,7 @@ class Inner {
@ReceiverDependentQual Inner(@ReceiverDependentQual Object... args) {}

void foo() {
// :: error: (new.class.type.invalid)
// :: error: (new.class.type.invalid) :: error: (varargs.type.incompatible)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the intuition behind this new error? There are no arguments to this constructor invocation, so what is incompatible?

@aosen-xiong aosen-xiong Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The err msg is:

VarargsConstructor.java:35: error: [new.class.type.invalid]
type annotation [@Lost] can not be applied to object creation

VarargsConstructor.java:35: error: [varargs.type.incompatible]
incompatible types in varargs.
  found   : @Lost Object @Top []
  required: @Lost Object @Top []

A zero-argument varargs invocation still creates an implicit empty array. The error occurs because viewpoint adaptation produces @Lost, which is non-reflexive in this test checker. With #1173, the error would be gone.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the connection to #1173? 1173 is about lost receivers for poly declared receiver methods. This is about arrays?

If the var args array is definitely empty, the Lost component type cannot do any harm. It seems overly conservative to forbid this call, doesn't it?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because in #1173 we changed Lost to be a subtype of Lost, this varags.type.incompatible error message will be gone.

Okay, I see your points.

I think even after the change in #1173, we should have

  1. If the argument is empty, allow the call.
  2. If the argument is not empty and the var arg is adapted to have a lost type, reject the call.

Inner a = new Inner();
// :: warning: (cast.unsafe.constructor.invocation)
Inner b = new @A Inner(new @A Object());
Expand All @@ -42,7 +43,8 @@ void foo() {
void invokeConstructor(@A Object aObj, @B Object bObj, @Top Object topObj) {
@A Object a = new @A Inner(aObj);
@B Object b = new @B Inner(bObj);
// :: error: (argument.type.incompatible) :: error: (new.class.type.invalid)
// :: error: (argument.type.incompatible) :: error: (new.class.type.invalid) :: error:
// (varargs.type.incompatible)
@Top Object top = new @Top Inner(topObj);
// :: error: (argument.type.incompatible)
new @A Inner(bObj);
Expand Down
Loading