-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Use [NonNullTypes] to interpret unannotated types in source #27807
Conversation
@@ -803,7 +813,7 @@ private NamespaceOrTypeSymbolWithAnnotations UnwrapAlias(NamespaceOrTypeOrAliasS | |||
if (symbol.IsAlias) | |||
{ | |||
AliasSymbol discarded; | |||
return NamespaceOrTypeSymbolWithAnnotations.Create(Compilation, (NamespaceOrTypeSymbol)UnwrapAlias(symbol.Symbol, out discarded, diagnostics, syntax, basesBeingResolved)); | |||
return NamespaceOrTypeSymbolWithAnnotations.CreateNonNull(NonNullTypes, (NamespaceOrTypeSymbol)UnwrapAlias(symbol.Symbol, out discarded, diagnostics, syntax, basesBeingResolved)); |
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 check whether this and the similar change below are covered by test. #Resolved
@@ -588,6 +593,11 @@ private bool IsByRefTarget(int slot) | |||
return false; | |||
} | |||
|
|||
private void ReportWarningW(SyntaxNode syntax) | |||
{ | |||
ReportStaticNullCheckingDiagnostics(ErrorCode.WRN_ConvertingNullableToNonNullable, syntax); |
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.
ReportStaticNullCheckingDiagnostics [](start = 12, length = 35)
📝 This makes it easy to set a breakpoint to catch all W warnings. #Closed
@AlekseyTs @cston I've run into some more non-trivial cycles. It got me thinking, does binding really need to care about merging the information from On one side, we'd have the |
@@ -588,6 +593,11 @@ private bool IsByRefTarget(int slot) | |||
return false; | |||
} | |||
|
|||
private void ReportWarningW(SyntaxNode syntax) |
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.
ReportWarningW [](start = 21, length = 14)
Consider naming ReportWWarning
. #Resolved
There are several tests where there is only Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/StaticNullChecking.cs:3489 in e83865f. [](commit_id = e83865f, deletion_comment = False) |
Debug.Assert(!info.HasValue || info.SignatureIndex == 0); | ||
|
||
if (info.HasValue && TryExtractValueFromAttribute(info.Handle, out value, s_attributeBooleanValueExtractor)) | ||
{ | ||
return true; | ||
} | ||
|
||
value = false; | ||
value = 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.
default [](start = 20, length = 7)
Consider using false
instead. #Closed
#region NonNullTypesAttribute | ||
|
||
private bool? _nonNullTypes; | ||
public bool? NonNullTypes |
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.
public bool? NonNullTypes [](start = 8, length = 25)
Should these NonNullTypes
properties be on C# attribute data types only: FieldEarlyWellKnownAttributeData
, etc.? #Closed
@@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.CSharp | |||
/// A specific location for binding. | |||
/// </summary> | |||
[Flags] | |||
internal enum BinderFlags : uint | |||
internal enum BinderFlags : ulong |
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.
ulong [](start = 32, length = 5)
Is this change needed? #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.
I have to say I was surprised by that too (I thought I'd be using the last bit, but not going over). The error I got on 1 << 31
is: Error CS0031 Constant value '-2147483648' cannot be converted to a 'uint'
In reply to: 195579166 [](ancestors = 195579166)
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.
@@ -670,6 +681,13 @@ public override TypeSymbolWithAnnotations AsNotNullableReferenceType() | |||
new NonLazyType(_typeSymbol, isNullable: false, _customModifiers); | |||
} | |||
|
|||
public override TypeSymbolWithAnnotations AsObliviousReferenceType() | |||
{ |
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.
{ [](start = 12, length = 1)
Debug.Assert(_isNullable != true);
#Resolved
{ | ||
get | ||
{ | ||
Debug.Assert(false); // PROTOTYPE(NullableReferenceTypes): Can we reach this? |
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.
// PROTOTYPE(NullableReferenceTypes): Can we reach this? [](start = 37, length = 56)
Perhaps: F([NotNullTypes]List<object?> arg = default(List<object>))
#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.
I still didn't manage to reach this. I'll keep PROTOTYPE for a follow-up.
In reply to: 195588470 [](ancestors = 195588470)
@@ -832,13 +832,15 @@ public virtual bool HasUnsupportedMetadata | |||
} | |||
|
|||
/// <summary> | |||
/// Is module/type/method/field/property/event/parameter definition opted out of nullable warnings. Not valid to call on non-definitions. | |||
/// Is module/type/method/field/property/event/parameter definition opted-in/out of treating un-annotated types as non-null. | |||
/// This is determined by the presence of the `[NonNullTypes]` attribute and whether the containing module utilizes nullable reference types. |
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.
and whether the containing module utilizes nullable reference types [](start = 81, length = 67)
Isn't this also [NonNullTypes]
? #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.
There is also defaulting logic on modules (currently based on language version). I'll update comment.
In reply to: 195588753 [](ancestors = 195588753)
@@ -6,25 +6,25 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols | |||
{ | |||
internal sealed class EventWellKnownAttributeData : CommonEventWellKnownAttributeData | |||
{ | |||
#region NullableOptOutAttribute | |||
#region NonNullTypesAttribute |
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.
NonNullTypesAttribute [](start = 16, length = 21)
Seems surprising that some AttributeData
cases are early, others are not. #Closed
@@ -6,25 +6,25 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols | |||
{ | |||
internal sealed class MethodWellKnownAttributeData : CommonMethodWellKnownAttributeData | |||
{ | |||
#region NullableOptOutAttribute | |||
#region NonNullTypesAttribute |
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.
NonNullTypesAttribute [](start = 16, length = 21)
This is also on CommonMethodEarlyWellKnownAttributeData
. Is that correct? #Closed
@@ -28,6 +28,7 @@ internal sealed class SourceOrdinaryMethodSymbol : SourceMemberMethodSymbol | |||
private ImmutableArray<ParameterSymbol> _lazyParameters; | |||
private TypeSymbolWithAnnotations _lazyReturnType; | |||
private bool _lazyIsVararg; | |||
private bool? _nonNullTypesFromAttributes; |
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.
_nonNullTypesFromAttributes [](start = 22, length = 27)
_lazyNonNullTypesFromAttributes
#Closed
4accd68
to
ba396d5
Compare
Let's remove these tests that expect the attribute to control warnings. Perhaps in a separate PR. #Resolved Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/StaticNullChecking.cs:24755 in 31429cd. [](commit_id = 31429cd88ba99d331ca9c3b96119f33e26461979, deletion_comment = False) |
I'm expecting to each unskip or remove them, in a follow-up PR. In reply to: 400424239 [](ancestors = 400424239) Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/StaticNullChecking.cs:24755 in 31429cd. [](commit_id = 31429cd88ba99d331ca9c3b96119f33e26461979, deletion_comment = False) |
@dotnet/roslyn-compiler for a second review. Thanks |
@cston From our discussion, I'm disallowing In reply to: 399260480 [](ancestors = 399260480,397410688) Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/StaticNullChecking.cs:2240 in e83865f. [](commit_id = e83865f, deletion_comment = False) |
@333fred for a second review when you get the chance. Thanks #Resolved |
[AttributeUsage( | ||
AttributeTargets.All, | ||
AllowMultiple = false)] | ||
[AttributeUsage(AttributeTargets.Class | |
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 not assembly? #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.
From our discussion, I added a note to work items (module:
target is indeed unfamiliar to developers). #Resolved
receiverArgument = CreateConversion(receiver, methodResult.Result.ConversionForArg(0), | ||
GetTypeOrReturnTypeWithAdjustedNullableAnnotations(receiverParameter).TypeSymbol, | ||
receiverArgument = CreateConversion(receiver, methodResult.Result.ConversionForArg(0), | ||
receiverParameter.Type.TypeSymbol, |
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.
[](start = 56, length = 13)
Nit: consider reformatting to have consistent indentation with the previous line. Looks like this is a victim of past renames.
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. One small formatting nits.
get | ||
{ | ||
// PROTOTYPE(NullableReferenceTypes): temporary solution to avoid cycle | ||
return SyntaxBasedNonNullTypes(this.AttributeDeclarationSyntaxList) ?? base.NonNullTypes; |
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.
@AlekseyTs In case this helps, this is the approach we had previously used for syntax-based detection of NonNullTypes.
The specific SyntaxBasedNonNullTypes
in this PR was very inefficient, but we could use that model and make the check cheaper (ie. avoid .ToString()
).
In a context where
NonNullTypes
istrue
, an unannotated type is interpreted as non-null. But in a context where it isfalse
, then such type is interpreted as null-oblivious.Annotated types (ie. with
?
) are unaffected.The main parts of this change
Symbol
to indicate the presence of the attribute (on symbol or containing symbol, with module symbols terminating the chain)Binder
(generally look for the containing symbol's context, except if a binding flag was set to break cycles)NonNullTypes
context into account[NonNullTypes]
attribute is currently recognized syntactically, rather that properly bound. That is a temporary solution to avoid the numerous code cycles that arose. I'll work on breaking those cycles next.What is not yet done:
[NonNullTypes]
targeting a return value or a parameter (will be a follow-up PR)SourceNamedTypeSymbol.MakeOneDeclaredBases
which I will investigate and fix in a separate PRNonNullTypes
attribute in source. The handling of this attribute in metadata will be a follow-up PR