-
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
Track additional state for "maybe null even if not nullable" #39778
Conversation
d045f46
to
9588a81
Compare
@dotnet/roslyn-compiler please review. |
Please delete the comments in source such as Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:78879 in b027ec9. [](commit_id = b027ec9, deletion_comment = True) |
This comment doesn't seem accurate any more and probably others in this test, please update them #Closed Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:82264 in b027ec9. [](commit_id = b027ec9, deletion_comment = True) |
Is this going to happen for all reference types, not just generics constrained to class? #Closed Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:117855 in e6474bf. [](commit_id = e6474bf, deletion_comment = False) |
Is this Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:118248 in b027ec9. [](commit_id = b027ec9, deletion_comment = False) |
Obviously it's not the same thing here, but I wondered if it might fall out in a similar way. In reply to: 554561256 [](ancestors = 554561256) Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:118248 in b027ec9. [](commit_id = b027ec9, deletion_comment = False) |
Does this Identity function provide the expected flow state for other combinations of constraints? e.g. Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:118444 in b027ec9. [](commit_id = b027ec9, deletion_comment = False) |
Seems like the answer is yes, it's needed (based on a later test) In reply to: 554561397 [](ancestors = 554561397,554561256) Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:118248 in b027ec9. [](commit_id = b027ec9, deletion_comment = False) |
It feels like we should also test Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:118572 in b027ec9. [](commit_id = b027ec9, deletion_comment = False) |
@@ -1043,46 +1041,70 @@ private enum AssignmentKind | |||
Conversion conversion = default, | |||
Location location = null) | |||
{ | |||
// PROTOTYPE: Fix callers so we don't have cases where valueType and targetType differ. |
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 which scenarios do they differ? #Closed
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 think there are three substantive comments remaining:
- Discards should allow null without warning. Possibly just file a separate issue for that.
TypeWithState.Create
should handle a type parameter constrained byint?
, which can occur by substitution. Currently it is treated the same as an unconstrained type parameter, which doesn't know if it can containnull
or not. Such type parameters do havenull
in their domain.SetStateAndTrackForFinally
should useJoin
when incorporating new state information.
} | ||
finally | ||
{ | ||
F0(t2); // 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.
I'm a little confused by this-- is it expected that we could throw out of the 'try' block at any point and then run the 'finally' block, so we have to be as pessimistic as possible here? #Closed
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.
Yes, we assume an exception could have been thrown between the assignments above, although perhaps we could do better for those simple assignments.
In reply to: 348225225 [](ancestors = 348225225)
verify(exprs[0], PublicNullableAnnotation.NotAnnotated, PublicNullableFlowState.MaybeNull); | ||
verify(exprs[1], PublicNullableAnnotation.Annotated, PublicNullableFlowState.MaybeNull); | ||
|
||
void verify(DefaultExpressionSyntax expr, PublicNullableAnnotation expectedAnnotation, PublicNullableFlowState expectedState) |
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.
consider putting expected values first or labeling in order to match the conventions of the xunit Assert methods. #ByDesign
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'll leave as is since this matches similar local functions in this class.
In reply to: 348226625 [](ancestors = 348226625)
Just curious, was this ever addressed by additional tests or comments elsewhere? In reply to: 554563195 [](ancestors = 554563195) Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:118444 in b027ec9. [](commit_id = b027ec9, deletion_comment = False) |
It doesn't look like any test was added in response to this, did I miss it by accident, or maybe miss a relevant existing test? In reply to: 554565234 [](ancestors = 554565234) Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:118572 in b027ec9. [](commit_id = b027ec9, deletion_comment = False) |
@RikkiGibson, @333fred, @gafter, all feedback has been addressed, thanks. |
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.
using System.Diagnostics.CodeAnalysis; | ||
class Program | ||
{ | ||
static T F0<T>(T t) => t ??= default; |
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 appears to still be using ??= #Closed
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 modulo a minor bit of test coverage
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 (commit 13)
/// <summary> | ||
/// Maybe null (type may be not nullable). | ||
/// </summary> | ||
MaybeDefault = 0b11, |
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.
Why 0b11
and not 0b10
? #ByDesign
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.
So we can (continue to) use bit-wise |
and &
for Join()
and Meet()
.
In reply to: 348763602 [](ancestors = 348763602)
Is there a version of this test where the method is invoked, stored into a local and then the local is returned? Essentially verifying that the state transfers through locals as well. #Resolved Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs:118649 in e6474bf. [](commit_id = e6474bf, deletion_comment = False) |
Track additional flow state to improve analysis of
[MaybeNull]T
values.The change includes:
NullableFlowState.MaybeDefault
for values of type parameters that are not constrained to be not nullable (types that cannot be annotated).[AllowNull]
and[return: MaybeNull]
on containing method signature now affect analysis within the method body.NullableFlowState.MaybeDefault
.Examples:
See dotnet/csharplang#2946.
Fixes #38638.
Fixes #37362.