Do not include value types in NullableAttribute byte[]#36519
Do not include value types in NullableAttribute byte[]#36519cston merged 7 commits intodotnet:masterfrom
Conversation
|
@dotnet/roslyn-compiler please review. |
| private NamedTypeSymbol _lazyBaseType = ErrorTypeSymbol.UnknownResultType; | ||
| private ImmutableArray<NamedTypeSymbol> _lazyInterfaces = default(ImmutableArray<NamedTypeSymbol>); | ||
| private NamedTypeSymbol _lazyDeclaredBaseType = ErrorTypeSymbol.UnknownResultType; | ||
| private NamedTypeSymbol _lazyDeclaredBaseTypeWithoutNullability = ErrorTypeSymbol.UnknownResultType; |
There was a problem hiding this comment.
private NamedTypeSymbol _lazyDeclaredBaseTypeWithoutNullability = ErrorTypeSymbol.UnknownResultType; [](start = 8, length = 100)
It doesn't look like adding this cache is necessary. Inside TypeKind.get we could check if we already have _lazyDeclaredBaseType and use that, otherwise we could resolve the type from metadata without applying any transforms, including tuple and dynamic, and use that type without caching it. #Closed
There was a problem hiding this comment.
Even better might be to bundle resolution of base type with calculating type kind for non-interfaces. Before we apply any transforms to the base type, calculate and set the type kind, then proceed with transforms.
In reply to: 294935242 [](ancestors = 294935242)
| - Nullable value type: the representation of the type argument only | ||
| - Value type: the representation of the type arguments in order including containing types | ||
| - Non-generic value type: skipped | ||
| - Generic value type: 0, followed by the representation of the type arguments in order including containing types |
There was a problem hiding this comment.
0, [](start = 21, length = 4)
just curious: why do we want to encode an annotation for a value type? Is this due to a concern for cycles when loading metadata? (if so, may be good to record rationale) #Resolved
There was a problem hiding this comment.
Yes, the reason that generic value types (and type parameters constrained to struct) include a 0 byte is to avoid cycles when loading types from metadata - in particular, when loading type parameters with constraint types. Simple (non-generic) value types are less of a concern.
I'll add a note to the document.
In reply to: 294943765 [](ancestors = 294943765)
| if (!expectedPreviously.SequenceEqual(expectedNow)) | ||
| { | ||
| position = 0; | ||
| Assert.True(underlyingType.ApplyNullableTransforms(0, ImmutableArray.Create(expectedPreviously), ref position, out updated) || position < expectedPreviously.Length); |
There was a problem hiding this comment.
underlyingType.ApplyNullableTransforms(0, ImmutableArray.Create(expectedPreviously), ref position, out updated) [](start = 28, length = 111)
Should this condition be negated? #Closed
There was a problem hiding this comment.
| return type.IsNullableType(); | ||
| } | ||
| else | ||
| return type.IsValueType && !type.IsTupleType; |
There was a problem hiding this comment.
type.IsValueType [](start = 19, length = 16)
Are we testing scenarios when concrete value type references within another type cannot be resolved from metadata (an assembly reference is missing, for example)? It looks like this might cause a confusion during ApplyNullableTransforms causing us to apply flags to wrong places.
|
Done with review pass (iteration 4) #Closed |
| VerifyBytes(globalNamespace.GetMember<FieldSymbol>("Program.F25").TypeWithAnnotations, new byte[] { 0, 1 }, new byte[] { 0, 1 }, "S<U!>"); | ||
| VerifyBytes(globalNamespace.GetMember<FieldSymbol>("Program.F31").TypeWithAnnotations, new byte[] { 0 }, new byte[] { 0 }, "V"); | ||
| VerifyBytes(globalNamespace.GetMember<FieldSymbol>("Program.F32").TypeWithAnnotations, new byte[] { 0, 0 }, new byte[] { 0 }, "V?"); | ||
| VerifyBytes(globalNamespace.GetMember<FieldSymbol>("Program.F33").TypeWithAnnotations, new byte[] { 1, 0 }, new byte[] { 1, 0 }, "V[]!"); |
There was a problem hiding this comment.
new byte[] { 1, 0 } [](start = 103, length = 19)
nit: consider using null for expectedPreviously when it is equals to expectedNow, as the actual value will be ignored.
jcouv
left a comment
There was a problem hiding this comment.
LGTM modulo Aleksey's feedback on removing cache. Thanks (iteration 4)
| { | ||
| // Decoding nullability might lead to a cycle calculating the base type. | ||
| // Instead, return early without updating the field. | ||
| return baseType; |
There was a problem hiding this comment.
return baseType; [](start = 24, length = 16)
No need to do dynamic and tuple transforms for this code path. #Closed
| } | ||
|
|
||
| [Fact] | ||
| public void EmitAttribute_ValueTypes_08() |
There was a problem hiding this comment.
EmitAttribute_ValueTypes_08 [](start = 20, length = 27)
I don't think this test covers the error scenario that I was interested in. I was thinking about the tests that deals with types coming from metadata, this test verifies types coming from source. #Resolved
AlekseyTs
left a comment
There was a problem hiding this comment.
LGTM (iteration 7), the tests can be followed up on in a separate PR.
* dotnet/master: (85 commits) Don't complete statement when typing semicolon inside comments in an argument list (dotnet#36521) Set focus to editor before finding text Add a bunch of nullability support to some code generation helpers Add 'annotations' and 'warnings' support to nullable directive (dotnet#36464) Fixed IDE services touching `notnull` constraint (dotnet#36508) Update compiler toolset to arcade version (dotnet#36549) Fix for 923157 Do not include value types in NullableAttribute byte[] (dotnet#36519) Fix a deadlock in InvokeOnUIThread Apply a hang mitigating timeout to UI thread operations Move to a different lowering from for nullable value types to work around a bug in TransformCompoundAssignmentLHS. Addressed PR feedback. Fix stack overflow in requesting syntax directives (dotnet#36347) crash on ClassifyUpdate for EventFields (dotnet#35962) fixing bad merge with refactoring that was checked in later added basic completion statement telemetry Remove duplication in AbstractSymbolCompletionProvider.CreateItems Disable move type when the options service isn't present (dotnet#36334) Fix crash where type inference doing method inference needs to drop nullability Revert "Use IVsSolution to look up IVsHierarchy by project GUID (dotnet#35746)" Fix parsing bug in invalid using statements (dotnet#36428) ...
Do not include a
0entry in thebyte[]for non-generic value types. The0is still included for generic value types, tuples, and type parameters constrained to value types.