Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
d804e2e
WIP
msridhar Jan 6, 2026
2c9c3f1
tweaks
msridhar Jan 6, 2026
a5ee613
Merge branch 'master' into lambda-poly-expression
msridhar Jan 6, 2026
808fb74
tweak
msridhar Jan 6, 2026
642a623
refactor
msridhar Jan 6, 2026
b6cb584
fix test case
msridhar Jan 6, 2026
cd9a4e3
Merge branch 'master' into lambda-poly-expression
msridhar Jan 7, 2026
3a36420
WIP
msridhar Jan 7, 2026
f528062
bug fix
msridhar Jan 7, 2026
a104dcc
comment and test case for #1307
msridhar Jan 7, 2026
c2c5808
fix nullaway error
msridhar Jan 7, 2026
9cd8239
Merge branch 'master' into method-ref-improve
msridhar Jan 7, 2026
fd64445
improve test
msridhar Jan 7, 2026
cae7447
remove unnecessary code and fix test
msridhar Jan 8, 2026
b84dd93
rename test file and move tests
msridhar Jan 8, 2026
6667ae3
a failing test we will handle in a follow up
msridhar Jan 8, 2026
05ec1ae
tweaks
msridhar Jan 8, 2026
c0031e0
cleanup
msridhar Jan 8, 2026
9a95c56
further cleanup
msridhar Jan 8, 2026
8d47ece
Merge branch 'master' into method-ref-improve
msridhar Jan 11, 2026
1a53741
Merge branch 'master' into method-ref-improve
msridhar Jan 12, 2026
6afc36b
Merge branch 'master' into method-ref-improve
msridhar Jan 13, 2026
468c520
WIP
msridhar Jan 11, 2026
a01a513
Merge branch 'master' into method-ref-generic-inference
msridhar Jan 14, 2026
2d7fa93
failing test
msridhar Jan 14, 2026
d67c661
fix test
msridhar Jan 14, 2026
9091dd1
Merge branch 'master' into method-ref-generic-inference
msridhar Jan 15, 2026
b736fe2
Merge branch 'master' into method-ref-generic-inference
msridhar Jan 15, 2026
fa16569
re-jigger logic
msridhar Jan 18, 2026
741de42
todos
msridhar Jan 18, 2026
fb60aee
WIP
msridhar Jan 19, 2026
ced8cae
WIP
msridhar Jan 19, 2026
029aa72
fix
msridhar Jan 19, 2026
dc1d9aa
complete test
msridhar Jan 19, 2026
659f169
another test
msridhar Jan 19, 2026
2c0cab4
WIP
msridhar Jan 19, 2026
4dfb323
fix test
msridhar Jan 19, 2026
4d50575
more tests
msridhar Jan 20, 2026
93a208d
WIP
msridhar Jan 20, 2026
ac4673b
cleanup and docs
msridhar Jan 20, 2026
ef71582
fix npe
msridhar Jan 20, 2026
6918968
Merge branch 'master' into method-ref-generic-inference
msridhar Jan 23, 2026
c4e25b3
Merge branch 'master' into method-ref-generic-inference
msridhar Jan 25, 2026
a8b1917
Merge branch 'master' into method-ref-generic-inference
msridhar Jan 25, 2026
4abedaf
Merge branch 'master' into method-ref-generic-inference
msridhar Feb 5, 2026
238a3e2
add a test for stream with values mapped to @Nullable; doesn't work yet
msridhar Feb 5, 2026
0e1b7ec
Merge branch 'master' into method-ref-generic-inference
msridhar Feb 5, 2026
1e9ab99
some improvements
msridhar Feb 5, 2026
16942b2
more cleanup
msridhar Feb 5, 2026
28bf098
add issue link
msridhar Feb 5, 2026
c76fbd5
Merge branch 'master' into method-ref-generic-inference
msridhar Feb 9, 2026
b90e54d
Merge branch 'master' into method-ref-generic-inference
msridhar Feb 10, 2026
2f924bb
add comment
msridhar Feb 10, 2026
de6b0ce
cleanup and todos
msridhar Feb 10, 2026
f695f56
test
msridhar Feb 11, 2026
8b4f0d0
another test case
msridhar Feb 12, 2026
3406847
yet another test
msridhar Feb 12, 2026
e2e735c
Add TODO comment
msridhar Feb 12, 2026
23bfde7
another comment
msridhar Feb 12, 2026
9a989da
add issue link
msridhar Feb 12, 2026
839d22c
comment and remove unnecessary check
msridhar Feb 13, 2026
a2d2b5d
test for new bug
msridhar Feb 13, 2026
5ce5c46
initial fix
msridhar Feb 13, 2026
d800190
WIP
msridhar Feb 13, 2026
69914e2
move method
msridhar Feb 14, 2026
5b2b3dd
refactoring and docs
msridhar Feb 14, 2026
93c4820
more cleanup
msridhar Feb 14, 2026
6ecb972
add a contract
msridhar Feb 14, 2026
d7e4772
remove incorrect comment in test
msridhar Feb 14, 2026
724e54c
tweak diagnostic message that is matched on
msridhar Feb 15, 2026
81f844f
Merge branch 'master' into method-ref-generic-inference
msridhar Feb 16, 2026
0fdd94d
review feedback
msridhar Feb 16, 2026
f952e8a
augment tests
msridhar Feb 16, 2026
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
Prev Previous commit
Next Next commit
WIP
  • Loading branch information
msridhar committed Feb 13, 2026
commit d8001903a141f5255121974c2e2f5ec0852a5482
32 changes: 30 additions & 2 deletions nullaway/src/main/java/com/uber/nullaway/NullAway.java
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@ private Description checkParamOverriding(
methodParamInd,
overridingMethod,
isOverridingMethodAnnotated,
memberReferenceTree,
jspecifyMemberReferenceMethodType);
// in the case where we have a parameter of a lambda expression, we do
// *not* force the parameter to be annotated with @Nullable; instead we "inherit"
Expand Down Expand Up @@ -962,8 +963,9 @@ private Description checkParamOverriding(
private boolean paramOfOverridingMethodIsNonNull(
VarSymbol paramSymbol,
int methodParamInd,
@SuppressWarnings("UnusedVariable") Symbol.@Nullable MethodSymbol overridingMethod,
Symbol.@Nullable MethodSymbol overridingMethod,
boolean isMethodAnnotated,
@Nullable MemberReferenceTree memberReferenceTree,
Type.@Nullable MethodType memberReferenceMethodType) {
boolean result = false;
if (isMethodAnnotated) {
Expand All @@ -976,7 +978,33 @@ private boolean paramOfOverridingMethodIsNonNull(
// when the overriding method is a member reference, also check that the parameter is not
// effectively @Nullable due to generics. memberReferenceMethodType should be the method type
// of the member reference after handling generics
Type paramType = memberReferenceMethodType.getParameterTypes().get(methodParamInd);
com.sun.tools.javac.util.List<Type> parameterTypes =
memberReferenceMethodType.getParameterTypes();
int memberRefParamIndex = methodParamInd;
if (memberReferenceTree != null
&& overridingMethod != null
&& overridingMethod.isVarArgs()
&& ((JCTree.JCMemberReference) memberReferenceTree).varargsElement != null) {
// With varargs adaptation, one or more functional-interface parameters can map to the
// varargs element type of the referenced method.
int varargsParamIndex = overridingMethod.getParameters().size() - 1;
if (methodParamInd >= varargsParamIndex) {
memberRefParamIndex = varargsParamIndex;
}
}
Type paramType = parameterTypes.get(memberRefParamIndex);
if (memberReferenceTree != null
&& overridingMethod != null
&& overridingMethod.isVarArgs()
&& ((JCTree.JCMemberReference) memberReferenceTree).varargsElement != null
&& methodParamInd >= overridingMethod.getParameters().size() - 1) {
Verify.verify(
paramType.getKind() == TypeKind.ARRAY,
"Expected array type for varargs parameter in %s, got %s",
memberReferenceTree,
paramType);
paramType = ((Type.ArrayType) paramType).getComponentType();
}
result = !Nullness.hasNullableAnnotation(paramType.getAnnotationMirrors().stream(), config);
}
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1018,39 +1018,36 @@ private void handleMethodRefInGenericMethodInference(

// For varargs references, the functional interface can map to fixed-arity form (single array
// argument at the varargs position) or variable-arity form (zero or more element arguments).
int fixedParamCount = referencedParamTypes.size() - 1;
int constrainedFixedParamCount = Math.min(fiParamCount, fixedParamCount);
int varargsParamPosition = referencedParamTypes.size() - 1;
int constrainedFixedParamCount = Math.min(fiParamCount, varargsParamPosition);
for (int i = 0; i < constrainedFixedParamCount; i++) {
solver.addSubtypeConstraint(
fiParamTypes.get(fiStartIndex + i), referencedParamTypes.get(i), false);
}
if (fiParamCount <= fixedParamCount) {
if (fiParamCount <= varargsParamPosition) {
// Not enough FI parameters to cover the varargs position, or exactly no varargs arguments.
Comment thread
msridhar marked this conversation as resolved.
Outdated
return;
}

Type varargsArrayType = referencedParamTypes.get(fixedParamCount);
Type varargsArrayType = referencedParamTypes.get(varargsParamPosition);
Verify.verify(
varargsArrayType.getKind() == TypeKind.ARRAY,
"Expected array type for varargs parameter in %s, got %s",
memberReferenceTree,
varargsArrayType);
Type varargsElementType = castToNonNull(types.elemtype(varargsArrayType));
int firstVarargsFiParamIndex = fiStartIndex + fixedParamCount;
int fiParamsAtVarargsPosition = fiParamCount - fixedParamCount;
Type singleVarargsFiParamType = fiParamTypes.get(firstVarargsFiParamIndex);
if (fiParamsAtVarargsPosition == 1
&& (singleVarargsFiParamType.getKind() == TypeKind.ARRAY
// Preserve existing inference behavior for unresolved type variables, where fixed
// arity adaptation was previously assumed.
|| singleVarargsFiParamType instanceof Type.TypeVar)) {
// Single array (or unresolved type variable) parameter can represent fixed-arity adaptation.
solver.addSubtypeConstraint(singleVarargsFiParamType, varargsArrayType, false);
JCTree.JCMemberReference javacMemberRef = (JCTree.JCMemberReference) memberReferenceTree;
int firstVarargsFiParamIndex = fiStartIndex + varargsParamPosition;
if (javacMemberRef.varargsElement == null) {
// javac resolved this member reference using non-varargs (fixed-arity) adaptation.
solver.addSubtypeConstraint(
fiParamTypes.get(firstVarargsFiParamIndex), varargsArrayType, false);
return;
}
for (int i = 0; i < fiParamsAtVarargsPosition; i++) {
solver.addSubtypeConstraint(
fiParamTypes.get(firstVarargsFiParamIndex + i), varargsElementType, false);
// javac resolved this member reference using varargs (variable-arity) adaptation.
// Use the element type from the referenced varargs array type so we preserve nullability
// annotations (JCMemberReference.varargsElement can lose them).
Type varargsElementType = castToNonNull(types.elemtype(varargsArrayType));
for (int i = varargsParamPosition; i < fiParamCount; i++) {
solver.addSubtypeConstraint(fiParamTypes.get(fiStartIndex + i), varargsElementType, false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,7 @@ void testConsume(String sNonNull, @Nullable String sNullable) {
consume(Util::take, sNonNull); // should be legal
// BUG: Diagnostic contains: passing @Nullable parameter 'sNullable' where @NonNull is required
consume(Util::take, sNullable);
consume(Util::takeNullableArgs, sNonNull); // legal due to array subtyping
// BUG: Diagnostic contains: passing @Nullable parameter 'sNullable' where @NonNull is required
consume(Util::takeNullableArgs, sNonNull);
consume(Util::takeNullableArgs, sNullable);
}
Comment thread
msridhar marked this conversation as resolved.
}
Expand Down