-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Revise compound assignment for nullable #70687
Revise compound assignment for nullable #70687
Conversation
65f4906
to
8391b57
Compare
8391b57
to
ded5ba6
Compare
node.Operator.Kind, | ||
node.Operator.Method, | ||
node.Operator.ReturnType ?? node.Type, | ||
node.LeftConversion as BoundConversion ?? node.Left, |
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.
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.
roslyn/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
Lines 546 to 547 in 003a34f
<!-- Could be a BoundConversion or, in some cases of an identity conversion, the LeftPlaceholder, or null for no conversion case --> | |
<Field Name="LeftConversion" Type="BoundExpression?" SkipInVisitor="true" Null="allow"/> |
The other possibility is that it is a BoundPlaceholder
, which to me didn't make sense to visit as if the operand is really being operated on by that placeholder. However, I don't think I tested to see what happens when we remove the as BoundConversion
.
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: No test is affected by the removal of as BoundConversion
. It'd be good to hunt one down.
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.
Opened #70751 to try and find a scenario which could be used as a starting point. I probably will not block the PR on it, though.
AdjustSetValue(left, ref resultType); | ||
TrackNullableStateForAssignment(node, leftLValueType, MakeSlot(node.Left), resultType); | ||
AdjustSetValue(node.Left, ref resultTypeWithState); | ||
Debug.Assert(MakeSlot(node) == -1); |
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.
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 wanted to indicate that the value stored in the LHS of the compound-assignment effectively drops any "sub-slot" information in either operand of the compound-assignment, i.e. the nullable state of fields of the operands. Showing that the entire compound-assignment never has a slot felt useful. See test CompoundAssignment_SubSlots
.
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.
In that case, shouldn't the assert use node.Left
rather than node
? (I don't think we ever create slots for binary operators.)
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.
A regular assignment can have a slot.
It's possible a compound assignment should have a slot for the same reason but I feel comfortable punting on it.
comp.VerifyEmitDiagnostics(); | ||
} | ||
|
||
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65546")] |
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.
70646?
// (19,9): warning CS8602: Dereference of a possibly null reference. | ||
// c1.f3.ToString(); // 3 | ||
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c1.f3").WithLocation(19, 9)); | ||
} |
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.
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
Show resolved
Hide resolved
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.
LGTM Thanks (iteration 3)
Addresses several nullable issues, mainly related to compound assignment. I made an effort to share code for visiting a normal binary operator with the code for visiting a compound assignment.
VisitCompoundAssignmentOperator
has been pretty much rewritten only using the original code as a reference. I would recommend that you review the old and new versions of the methods separately as the diff may be a little noisy.Other minor adjustments in the PR include:
ReportNullableAssignmentIfNecessary
and instead ensures that we pass along the default arguments BitVector so that we set_disableDiagnostics
in the right places.[AllowNull]
. Now, any "sanitizing" of the value going into the property will not apply until the property is actually read again. This more precisely reflects the semantics of this scenario.