Skip to content

Improve cast warnings/errors logic#1049

Open
aosen-xiong wants to merge 66 commits intoeisop:masterfrom
aosen-xiong:haifeng-typecast
Open

Improve cast warnings/errors logic#1049
aosen-xiong wants to merge 66 commits intoeisop:masterfrom
aosen-xiong:haifeng-typecast

Conversation

@aosen-xiong
Copy link
Copy Markdown
Collaborator

@aosen-xiong aosen-xiong commented Jan 5, 2025

Cherry-pick #337
Merge with eisop/guava#10

@wmdietl wmdietl changed the title Improve type cast Improve cast warnings/errors logic Jan 5, 2025
@aosen-xiong aosen-xiong requested a review from wmdietl January 6, 2025 02:06
@aosen-xiong aosen-xiong assigned wmdietl and unassigned aosen-xiong Jan 6, 2025
Copy link
Copy Markdown
Member

@wmdietl wmdietl left a comment

Choose a reason for hiding this comment

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

Thanks for picking up this PR!

public CastInit() {
@UnknownInitialization CastInit t1 = (@UnknownInitialization CastInit) this;
// :: warning: (cast.unsafe)
// :: error: (cast.incomparable)
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.

Does this change make sense to you? @UnknownInitialization is the top of this hierarchy and @Initialized is a subtype. So why isn't this still cast.unsafe?

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.

I think this error message is for @Initialized CastInit t2 = (@Initialized CastInit) this; and as this is in the constructor, so this is @UnderInitialization and is casting to @Initialized, so the cast is incomparable.

@GuardSatisfied Object o3,
@GuardedByBottom Object o4) {
String s1 = (String) o1;
// :: error: (cast.incomparable)
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.

This is incompatible with the comment on line 9 - there should be no errors in this method.

@Signed Integer x = s.bar(local);
}

class Inner<T extends @UnknownSignedness Object> {
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.

Can you rename the type parameter T to make the code easier to read.

"cast.unsafe",
exprType.toString(true),
castType.toString(true));
} else if (castResult == TypecastKind.ERROR) {
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.

Why does this only handle WARNING and ERROR and not also at least NOT_UPCAST?
It seems a bit odd to have the TypecastKind with five values if isTypeCastSafe only returns three of the options.
Can you think of cleaning up the logic and the enum to make this easier to follow? Maybe there should be two separate enums, one for isTypeCastSafe and one for isUpcast?

AnnotatedDeclaredType castDeclared = (AnnotatedDeclaredType) castType;
AnnotationMirrorSet bounds =
atypeFactory.getTypeDeclarationBounds(castDeclared.getUnderlyingType());
protected TypecastKind isTypeCastSafe(
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.

A method that starts with is should usually return a boolean. Can you think of a more appropriate name?
We are already breaking all existing clients, so we might as well pick a better name.

@IntVal({0, 1}) int ac = (@IntVal({0, 1}) int) input;
@IntVal({0, 1, 2}) int sc = (@IntVal({0, 1, 2}) int) input;
// :: warning: (cast.unsafe)
// :: error: (cast.incomparable)
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.

Isn't this a cast from "0 or 1" to "definitely 1", so a downcast? Why is this incomparable now?

// Without the `(byte)` cast, all of these produce the following javac error:
// error: incompatible types: possible lossy conversion from int to byte
// The Value Checker's `cast.unsafe` error is analogous and is desirable.
// The Value Checker's `cast.incomparable` error is analogous and is desirable.
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.

Also doesn't seem like this should be incomparable...

* @return whether the arguments are the same type variables
*/
public static boolean areSameTypeVariables(TypeVariable v1, TypeVariable v2) {
return v1.asElement().getSimpleName() == v2.asElement().getSimpleName();
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.

This seems really undesirable. Two different type variable that have the same simple name "T" are not the same. Can you think of better logic for the single use of this function?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants