-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[CS] Diagnose misuse of CheckedCastExpr with ~= #76644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the contribution! I left a few comments inline but overall this looks good!
@@ -1419,6 +1419,11 @@ ERROR(optional_chain_isnt_chaining,none, | |||
()) | |||
ERROR(pattern_in_expr,none, | |||
"%0 cannot appear in an expression", (DescriptivePatternKind)) | |||
ERROR(invalid_cast_in_pattern,none, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's split this into three distinct diagnostics instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, in retrospect I did overload this unnecessarily.
lib/Sema/CSDiagnostics.cpp
Outdated
diagnose(2).fixItReplace(isExpr->getAsLoc(), "as"); | ||
return true; | ||
} | ||
llvm_unreachable("There is no other kind of checked cast!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: let's just return false;
here so that we get a "failed to produce a diagnostic" instead of a crash.
lib/Sema/CSGen.cpp
Outdated
if (!BE || !isPatternMatchingOperator(BE->getFn())) | ||
return ignoreInvalidPattern(); | ||
CS.recordFix(IgnoreInvalidCastInPattern::create( | ||
CS, CS.getConstraintLocator(castExpr))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it belongs in InvalidPatternInExprFailure
, I don't think we need a special fix kind for this, only a tailored diagnostic type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I like that better too.
@xedin Thanks for the review! Will address your comments shortly. |
Please re-request a review once you are done to help me keep track of this. |
cc5f26f
to
74b00a8
Compare
lib/Sema/CSGen.cpp
Outdated
if (BE && isPatternMatchingOperator(BE->getFn())) { | ||
anchor = castExpr; | ||
isInvalidCast = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say all this logic here can go directly into diagnoseInvalidCheckedCast
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, the only issue I run into with it there is with tuples and emitting multiple of the same error. I was doing it here so I could put the anchor at the CheckedCastExpr and then since the locator is uniqued on that, we wouldn't get the multiple errors. However, maybe that was not a good way for me to go about it. Also, I may have misunderstood your instruction, with the diagnostic -- is it better to create just a specialized function like diagnoseInvalidCheckedCast
? Or a separate subclass of FailureDiagnostic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try moving the logic into the diagnostic function and then use hasFixFor
potentially to see if we can skip diagnosing a tuple.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it better to create just a specialized function like diagnoseInvalidCheckedCast? Or a separate subclass of FailureDiagnostic?
Either way is fine, up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try moving the logic into the diagnostic function and then use hasFixFor potentially to see if we can skip diagnosing a tuple.
Hm, it's the same diagnostic but at a different location in the expression because the fix gets anchored on each invalid pattern, right? I think that's fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you're right, fix is anchored to each invalid pattern. Good to know it's okay, will remove that check then.
0863d43
to
39cc887
Compare
Using an unwrap operator with 'as' or the wrong keyword (i.e. `is`) when already checking a cast via ~= results in error: 'pattern variable binding cannot appear in an expression'. Add a diagnostic that provides more guidance and a fix-it for the removal of ?/! or replacement of 'is' with 'as'.
39cc887
to
f0eef0f
Compare
@swift-ci please test |
@swift-ci please test |
@swift-ci please test Windows platform |
swiftlang/swift-testing#731 |
@swift-ci please test macOS platform |
Issue
When applying unwrap operator to 'as' or using 'is' in a type-cast pattern (specifically one that binds a value), the diagnostic for the resulting error could provide more guidance and suggest a fix-it.
Example with current diagnostic:
Fix
invalid_cast_in_pattern
and an associated fix-it to remove !/? or replace 'is' with 'as'.Example with new diagnostic:
Resolves #44631.