Skip to content

Commit c48800f

Browse files
authored
Correct the way explicit annotations are handled in type argument inference
1 parent 76f8226 commit c48800f

10 files changed

Lines changed: 198 additions & 83 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package open.falsepos;
2+
3+
import java.util.Optional;
4+
import org.checkerframework.checker.nullness.qual.NonNull;
5+
import org.checkerframework.checker.nullness.qual.Nullable;
6+
7+
public class Issue6740 {
8+
9+
static <A> Optional<@NonNull A> ofNullable(@Nullable A value) {
10+
throw new RuntimeException();
11+
}
12+
13+
<B> @Nullable B getNullable(Class<B> type) {
14+
throw new RuntimeException();
15+
}
16+
17+
<C> Optional<@NonNull C> getOpt(int index, Class<C> type) {
18+
return ofNullable(getNullable(type));
19+
}
20+
}

checker/tests/nullness/flow/TestNullnessUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void testArr1(@Nullable Object @NonNull [] a) {
2323
// one way to use as a cast:
2424
@NonNull Object[] l2 = NullnessUtil.castNonNullDeep(a);
2525
// Careful, the non-deep version only casts the main modifier.
26-
// :: error: (type.arguments.not.inferred) :: error: (assignment)
26+
// :: error: (assignment)
2727
@NonNull Object[] l2b = NullnessUtil.castNonNull(a);
2828
// OK
2929
@Nullable Object[] l2c = NullnessUtil.castNonNull(a);
@@ -33,7 +33,7 @@ void testArr1b(@Nullable Object @Nullable [] a) {
3333
// one way to use as a cast:
3434
@NonNull Object[] l2 = NullnessUtil.castNonNullDeep(a);
3535
// Careful, the non-deep version only casts the main modifier.
36-
// :: error: (type.arguments.not.inferred) :: error: (assignment)
36+
// :: error: (assignment)
3737
@NonNull Object[] l2b = NullnessUtil.castNonNull(a);
3838
// OK
3939
@Nullable Object[] l2c = NullnessUtil.castNonNull(a);

framework/src/main/java/org/checkerframework/framework/util/typeinference8/constraint/Expression.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public ReductionResult reduce(Java8InferenceContext context) {
9191
s = new ProperType(expression, context);
9292
} else {
9393
AnnotatedTypeMirror atm = context.typeFactory.getAnnotatedType(expression);
94-
s = getT().create(atm, atm.getUnderlyingType());
94+
s = getT().create(atm, atm.getUnderlyingType(), false);
9595
}
9696
return new Typing(this, s, T, TypeConstraint.Kind.TYPE_COMPATIBILITY);
9797
}
@@ -200,7 +200,7 @@ private ReductionResult reduceMethodRef(Java8InferenceContext context) {
200200
AbstractType referenceType;
201201
if (context.isLambdaParam(preColonTree)) {
202202
AnnotatedTypeMirror atm = context.typeFactory.getAnnotatedType(preColonTree);
203-
referenceType = T.create(atm, atm.getUnderlyingType());
203+
referenceType = T.create(atm, atm.getUnderlyingType(), false);
204204
} else {
205205
if (MemberReferenceKind.getMemberReferenceKind(memRef).isUnbound()) {
206206
AnnotatedTypeMirror atm =

framework/src/main/java/org/checkerframework/framework/util/typeinference8/types/AbstractType.java

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,19 @@ public enum Kind {
6868
/** The {@link AnnotatedTypeFactory}. */
6969
protected final AnnotatedTypeFactory typeFactory;
7070

71+
/** Whether the annotations on this type should be ignored. */
72+
public final boolean ignoreAnnotations;
73+
7174
/**
7275
* Creates an {@link AbstractType}.
7376
*
7477
* @param context the context object
78+
* @param ignoreAnnotations whether the annotations on this type should be ignored
7579
*/
76-
protected AbstractType(Java8InferenceContext context) {
80+
protected AbstractType(Java8InferenceContext context, boolean ignoreAnnotations) {
7781
this.context = context;
7882
this.typeFactory = context.typeFactory;
83+
this.ignoreAnnotations = ignoreAnnotations;
7984
}
8085

8186
/**
@@ -126,9 +131,11 @@ public final TypeKind getTypeKind() {
126131
*
127132
* @param atm annotated type mirror
128133
* @param type type mirror
134+
* @param ignoreAnnotations whether the annotations on this type should be ignored
129135
* @return the new type
130136
*/
131-
public abstract AbstractType create(AnnotatedTypeMirror atm, TypeMirror type);
137+
public abstract AbstractType create(
138+
AnnotatedTypeMirror atm, TypeMirror type, boolean ignoreAnnotations);
132139

133140
/**
134141
* Return the underlying Java type without inference variables.
@@ -183,7 +190,9 @@ public List<ProperType> getTypeParameterBounds() {
183190

184191
for (AnnotatedTypeParameterBounds bound : typeVars) {
185192
TypeVariable typeVariable = (TypeVariable) javaEle.next().asType();
186-
bounds.add(new ProperType(bound.getUpperBound(), typeVariable.getUpperBound(), context));
193+
bounds.add(
194+
new ProperType(
195+
bound.getUpperBound(), typeVariable.getUpperBound(), context, ignoreAnnotations));
187196
}
188197
return bounds;
189198
}
@@ -197,7 +206,7 @@ public List<ProperType> getTypeParameterBounds() {
197206
public AbstractType capture(Java8InferenceContext context) {
198207
AnnotatedTypeMirror capturedType =
199208
context.typeFactory.applyCaptureConversion(getAnnotatedType());
200-
return create(capturedType, capturedType.getUnderlyingType());
209+
return create(capturedType, capturedType.getUnderlyingType(), ignoreAnnotations);
201210
}
202211

203212
/**
@@ -228,7 +237,7 @@ public AbstractType asSuper(TypeMirror superType) {
228237
AnnotatedTypeMirror.createType(superType, typeFactory, type.isDeclaration());
229238
typeFactory.initializeAtm(superAnnotatedType);
230239
AnnotatedTypeMirror asSuper = AnnotatedTypes.asSuper(typeFactory, type, superAnnotatedType);
231-
return create(asSuper, asSuper.getUnderlyingType());
240+
return create(asSuper, asSuper.getUnderlyingType(), ignoreAnnotations);
232241
}
233242

234243
/**
@@ -277,7 +286,7 @@ public AbstractType getFunctionTypeReturnType() {
277286
if (returnType.getKind() == TypeKind.VOID) {
278287
return null;
279288
}
280-
return create(returnType, returnTypeJava);
289+
return create(returnType, returnTypeJava, ignoreAnnotations);
281290
} else {
282291
return null;
283292
}
@@ -297,7 +306,7 @@ public List<AbstractType> getFunctionTypeParameterTypes() {
297306
List<AbstractType> params = new ArrayList<>();
298307
Iterator<? extends TypeMirror> iter = paramsTypeMirror.iterator();
299308
for (AnnotatedTypeMirror param : pair.first.getParameterTypes()) {
300-
params.add(create(param, iter.next()));
309+
params.add(create(param, iter.next(), ignoreAnnotations));
301310
}
302311
return params;
303312
} else {
@@ -385,7 +394,7 @@ public AbstractType replaceTypeArgs(List<AbstractType> args) {
385394
}
386395
newType.setTypeArguments(argTypes);
387396
newType.replaceAnnotations(getAnnotatedType().getPrimaryAnnotations());
388-
return create(newType, newTypeJava);
397+
return create(newType, newTypeJava, ignoreAnnotations);
389398
}
390399

391400
/**
@@ -416,7 +425,7 @@ public AbstractType getMostSpecificArrayType() {
416425
TypeMirror typeMirror =
417426
TypesUtils.getMostSpecificArrayType(getJavaType(), context.modelTypes);
418427
if (msat != null) {
419-
return create(msat, typeMirror);
428+
return create(msat, typeMirror, ignoreAnnotations);
420429
}
421430
return null;
422431
}
@@ -466,7 +475,7 @@ public List<AbstractType> getIntersectionBounds() {
466475
List<AbstractType> bounds = new ArrayList<>();
467476
for (AnnotatedTypeMirror bound :
468477
((AnnotatedIntersectionType) getAnnotatedType()).directSupertypes()) {
469-
bounds.add(create(bound, iter.next()));
478+
bounds.add(create(bound, iter.next(), ignoreAnnotations));
470479
}
471480
return bounds;
472481
}
@@ -478,7 +487,10 @@ public List<AbstractType> getIntersectionBounds() {
478487
*/
479488
public AbstractType getTypeVarUpperBound() {
480489
TypeMirror javaUpperBound = ((TypeVariable) getJavaType()).getUpperBound();
481-
return create(((AnnotatedTypeVariable) getAnnotatedType()).getUpperBound(), javaUpperBound);
490+
return create(
491+
((AnnotatedTypeVariable) getAnnotatedType()).getUpperBound(),
492+
javaUpperBound,
493+
ignoreAnnotations);
482494
}
483495

484496
/**
@@ -490,7 +502,10 @@ public AbstractType getTypeVarUpperBound() {
490502
*/
491503
public AbstractType getTypeVarLowerBound() {
492504
TypeMirror lowerBound = ((TypeVariable) getJavaType()).getLowerBound();
493-
return create(((AnnotatedTypeVariable) getAnnotatedType()).getLowerBound(), lowerBound);
505+
return create(
506+
((AnnotatedTypeVariable) getAnnotatedType()).getLowerBound(),
507+
lowerBound,
508+
ignoreAnnotations);
494509
}
495510

496511
/**
@@ -530,7 +545,7 @@ public List<AbstractType> getTypeArguments() {
530545
List<AbstractType> list = new ArrayList<>();
531546
for (AnnotatedTypeMirror typeArg :
532547
((AnnotatedDeclaredType) getAnnotatedType()).getTypeArguments()) {
533-
list.add(create(typeArg, iter.next()));
548+
list.add(create(typeArg, iter.next(), ignoreAnnotations));
534549
}
535550
return list;
536551
}
@@ -571,7 +586,9 @@ public AbstractType getWildcardLowerBound() {
571586
if (getJavaType().getKind() == TypeKind.WILDCARD) {
572587
WildcardType wild = (WildcardType) getJavaType();
573588
return create(
574-
((AnnotatedWildcardType) getAnnotatedType()).getSuperBound(), wild.getSuperBound());
589+
((AnnotatedWildcardType) getAnnotatedType()).getSuperBound(),
590+
wild.getSuperBound(),
591+
ignoreAnnotations);
575592
}
576593
return null;
577594
}
@@ -587,7 +604,10 @@ public AbstractType getWildcardUpperBound() {
587604
if (upperBoundJava == null) {
588605
upperBoundJava = context.object.getJavaType();
589606
}
590-
return create(((AnnotatedWildcardType) getAnnotatedType()).getExtendsBound(), upperBoundJava);
607+
return create(
608+
((AnnotatedWildcardType) getAnnotatedType()).getExtendsBound(),
609+
upperBoundJava,
610+
ignoreAnnotations);
591611
} else {
592612
return null;
593613
}
@@ -600,7 +620,7 @@ public AbstractType getWildcardUpperBound() {
600620
*/
601621
public AbstractType getErased() {
602622
TypeMirror typeMirror = context.env.getTypeUtils().erasure(getJavaType());
603-
return create(getAnnotatedType().getErased(), typeMirror);
623+
return create(getAnnotatedType().getErased(), typeMirror, ignoreAnnotations);
604624
}
605625

606626
/**
@@ -611,7 +631,10 @@ public AbstractType getErased() {
611631
public final AbstractType getComponentType() {
612632
if (getJavaType().getKind() == TypeKind.ARRAY) {
613633
TypeMirror javaType = ((ArrayType) getJavaType()).getComponentType();
614-
return create(((AnnotatedArrayType) getAnnotatedType()).getComponentType(), javaType);
634+
return create(
635+
((AnnotatedArrayType) getAnnotatedType()).getComponentType(),
636+
javaType,
637+
ignoreAnnotations);
615638
} else {
616639
return null;
617640
}
@@ -634,6 +657,9 @@ public boolean equals(Object o) {
634657
}
635658

636659
AbstractType that = (AbstractType) o;
660+
if (ignoreAnnotations != that.ignoreAnnotations) {
661+
return false;
662+
}
637663

638664
if (!context.equals(that.context)) {
639665
return false;

framework/src/main/java/org/checkerframework/framework/util/typeinference8/types/InferenceFactory.java

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -871,20 +871,33 @@ public ProperType lub(Set<ProperType> properTypes) {
871871
if (properTypes.isEmpty()) {
872872
return null;
873873
}
874-
TypeMirror tiTypeMirror = null;
875-
AnnotatedTypeMirror ti = null;
876-
for (ProperType liProperType : properTypes) {
877-
AnnotatedTypeMirror li = liProperType.getAnnotatedType();
878-
TypeMirror liTypeMirror = liProperType.getJavaType();
879-
if (ti == null) {
880-
ti = li;
881-
tiTypeMirror = liTypeMirror;
874+
875+
TypeMirror lubTM = null;
876+
AnnotatedTypeMirror lubATM = null;
877+
boolean ignoreAnnotations = false;
878+
for (ProperType properType : properTypes) {
879+
AnnotatedTypeMirror atm = properType.getAnnotatedType();
880+
TypeMirror tm = properType.getJavaType();
881+
if (lubATM == null) {
882+
lubATM = atm;
883+
lubTM = tm;
884+
ignoreAnnotations = properType.ignoreAnnotations;
882885
} else {
883-
tiTypeMirror = lub(context.env, tiTypeMirror, liTypeMirror);
884-
ti = AnnotatedTypes.leastUpperBound(typeFactory, ti, li, tiTypeMirror);
886+
lubTM = lub(context.env, lubTM, tm);
887+
if (properType.ignoreAnnotations == ignoreAnnotations) {
888+
lubATM = AnnotatedTypes.leastUpperBound(typeFactory, lubATM, atm, lubTM);
889+
} else if (properType.ignoreAnnotations) {
890+
lubATM =
891+
AnnotatedTypes.asSuper(
892+
typeFactory, lubATM, AnnotatedTypeMirror.createType(lubTM, typeFactory, false));
893+
} else {
894+
lubATM =
895+
AnnotatedTypes.asSuper(
896+
typeFactory, atm, AnnotatedTypeMirror.createType(lubTM, typeFactory, false));
897+
}
885898
}
886899
}
887-
return new ProperType(ti, tiTypeMirror, context);
900+
return new ProperType(lubATM, lubTM, context, ignoreAnnotations);
888901
}
889902

890903
/**
@@ -921,22 +934,29 @@ public AbstractType glb(AbstractType a, AbstractType b) {
921934
AnnotatedTypeMirror aAtm = a.getAnnotatedType();
922935
AnnotatedTypeMirror bAtm = b.getAnnotatedType();
923936
AnnotatedTypeMirror glbATM = AnnotatedTypes.annotatedGLB(typeFactory, aAtm, bAtm);
937+
if (a.ignoreAnnotations != b.ignoreAnnotations) {
938+
if (a.ignoreAnnotations) {
939+
glbATM.replaceAnnotations(bAtm.getPrimaryAnnotations());
940+
} else {
941+
glbATM.replaceAnnotations(aAtm.getPrimaryAnnotations());
942+
}
943+
}
924944
if (context.types.isSameType(aJavaType, (Type) glb)) {
925-
return a.create(glbATM, glb);
945+
return a.create(glbATM, glb, false);
926946
}
927947

928948
if (context.types.isSameType(bJavaType, (Type) glb)) {
929-
return b.create(glbATM, glb);
949+
return b.create(glbATM, glb, false);
930950
}
931951

932952
if (a.isInferenceType()) {
933-
return a.create(glbATM, glb);
953+
return a.create(glbATM, glb, false);
934954
} else if (b.isInferenceType()) {
935-
return b.create(glbATM, glb);
955+
return b.create(glbATM, glb, false);
936956
}
937957

938958
assert a.isProper() && b.isProper();
939-
return new ProperType(glbATM, glb, context);
959+
return new ProperType(glbATM, glb, context, a.ignoreAnnotations && b.ignoreAnnotations);
940960
}
941961

942962
/**
@@ -1104,7 +1124,7 @@ public AbstractType createFreshTypeVariable(
11041124
}
11051125
context.typeFactory.capturedTypeVarSubstitutor.substitute(
11061126
typeVariable, Collections.singletonMap(typeVariable.getUnderlyingType(), typeVariable));
1107-
return upperBound.create(typeVariable, freshTypeVariable);
1127+
return upperBound.create(typeVariable, freshTypeVariable, false);
11081128
}
11091129

11101130
/**

0 commit comments

Comments
 (0)