-
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
Support nullable annotations on unconstrained type parameters #45993
Changes from all commits
378b787
0c6ee3e
0b226df
f90b6dc
fdb9761
75ad5d2
45f25fa
4335656
0d99acd
5bf7059
114b1f1
41772fd
08ab997
034d794
82d5514
8e9cd02
ab7f8c6
bfb6fba
8e24e99
f29fa09
51cef0c
761359d
085ec99
2a7db06
18f5abb
6fff28c
280bdf4
ef0908c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1493,12 +1493,14 @@ internal bool HasTopLevelNullabilityIdentityConversion(TypeWithAnnotations sourc | |
return true; | ||
} | ||
|
||
if (source.IsPossiblyNullableTypeTypeParameter() && !destination.IsPossiblyNullableTypeTypeParameter()) | ||
var sourceIsPossiblyNullableTypeParameter = IsPossiblyNullableTypeTypeParameter(source); | ||
var destinationIsPossiblyNullableTypeParameter = IsPossiblyNullableTypeTypeParameter(destination); | ||
if (sourceIsPossiblyNullableTypeParameter && !destinationIsPossiblyNullableTypeParameter) | ||
{ | ||
return destination.NullableAnnotation.IsAnnotated(); | ||
} | ||
|
||
if (destination.IsPossiblyNullableTypeTypeParameter() && !source.IsPossiblyNullableTypeTypeParameter()) | ||
if (destinationIsPossiblyNullableTypeParameter && !sourceIsPossiblyNullableTypeParameter) | ||
{ | ||
return source.NullableAnnotation.IsAnnotated(); | ||
} | ||
|
@@ -1523,14 +1525,21 @@ internal bool HasTopLevelNullabilityImplicitConversion(TypeWithAnnotations sourc | |
return true; | ||
} | ||
|
||
if (source.IsPossiblyNullableTypeTypeParameter() && !destination.IsPossiblyNullableTypeTypeParameter()) | ||
if (IsPossiblyNullableTypeTypeParameter(source) && !IsPossiblyNullableTypeTypeParameter(destination)) | ||
{ | ||
return false; | ||
} | ||
|
||
return !source.NullableAnnotation.IsAnnotated(); | ||
} | ||
|
||
private static bool IsPossiblyNullableTypeTypeParameter(in TypeWithAnnotations typeWithAnnotations) | ||
{ | ||
var type = typeWithAnnotations.Type; | ||
return type is object && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It looks like we dropped There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes. Callers above are explicitly checking In reply to: 456696256 [](ancestors = 456696256) |
||
(type.IsPossiblyNullableReferenceTypeTypeParameter() || type.IsNullableTypeOrTypeParameter()); | ||
} | ||
|
||
/// <summary> | ||
/// Returns false if the source does not have an implicit conversion to the destination | ||
/// because of either incompatible top level or nested nullability. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1363,7 +1363,7 @@ | |
<value>The return type for ++ or -- operator must match the parameter type or be derived from the parameter type</value> | ||
</data> | ||
<data name="ERR_TypeConstraintsMustBeUniqueAndFirst" xml:space="preserve"> | ||
<value>The 'class', 'struct', 'unmanaged', and 'notnull' constraints cannot be combined or duplicated, and must be specified first in the constraints list.</value> | ||
<value>The 'class', 'struct', 'unmanaged', 'notnull', and 'default' constraints cannot be combined or duplicated, and must be specified first in the constraints list.</value> | ||
</data> | ||
<data name="ERR_RefValBoundWithClass" xml:space="preserve"> | ||
<value>'{0}': cannot specify both a constraint class and the 'class' or 'struct' constraint</value> | ||
|
@@ -5608,7 +5608,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ | |
<value>Explicit application of 'System.Runtime.CompilerServices.NullableAttribute' is not allowed.</value> | ||
</data> | ||
<data name="ERR_NullableUnconstrainedTypeParameter" xml:space="preserve"> | ||
<value>A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint.</value> | ||
<value>A nullable type parameter must be known to be a value type or non-nullable reference type unless language version '{0}' or greater is used. Consider changing the language version or adding a 'class', 'struct', or type constraint.</value> | ||
</data> | ||
<data name="ERR_NullableOptionNotAvailable" xml:space="preserve"> | ||
<value>Invalid '{0}' value: '{1}' for C# {2}. Please use language version '{3}' or greater.</value> | ||
|
@@ -5736,6 +5736,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ | |
<data name="IDS_FeatureNullPointerConstantPattern" xml:space="preserve"> | ||
<value>null pointer constant pattern</value> | ||
</data> | ||
<data name="IDS_FeatureDefaultTypeParameterConstraint" xml:space="preserve"> | ||
<value>default type parameter constraints</value> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It feels like the name of the feature isn't very clear, especially that There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. This message is only reported for uses of In reply to: 456603253 [](ancestors = 456603253,456602711) |
||
</data> | ||
<data name="ERR_WrongNumberOfSubpatterns" xml:space="preserve"> | ||
<value>Matching the tuple type '{0}' requires '{1}' subpatterns, but '{2}' subpatterns are present.</value> | ||
</data> | ||
|
@@ -6021,6 +6024,12 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ | |
<data name="ERR_OverrideValConstraintNotSatisfied" xml:space="preserve"> | ||
<value>Method '{0}' specifies a 'struct' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is not a non-nullable value type.</value> | ||
</data> | ||
<data name="ERR_OverrideDefaultConstraintNotSatisfied" xml:space="preserve"> | ||
<value>Method '{0}' specifies a 'default' constraint for type parameter '{1}', but corresponding type parameter '{2}' of overridden or explicitly implemented method '{3}' is constrained to a reference type or a value type.</value> | ||
</data> | ||
<data name="ERR_DefaultConstraintOverrideOnly" xml:space="preserve"> | ||
<value>The 'default' constraint is valid on override and explicit interface implementation methods only.</value> | ||
</data> | ||
<data name="IDS_OverrideWithConstraints" xml:space="preserve"> | ||
<value>constraints for override and explicit interface implementation methods</value> | ||
</data> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,6 +105,7 @@ internal enum MessageID | |
|
||
// available | ||
|
||
IDS_FeatureDefaultTypeParameterConstraint = MessageBase + 12689, | ||
IDS_FeatureNullPropagatingOperator = MessageBase + 12690, | ||
IDS_FeatureExpressionBodiedMethod = MessageBase + 12691, | ||
IDS_FeatureExpressionBodiedProperty = MessageBase + 12692, | ||
|
@@ -208,6 +209,7 @@ internal enum MessageID | |
IDS_FeatureRecords = MessageBase + 12782, | ||
IDS_FeatureNullPointerConstantPattern = MessageBase + 12783, | ||
IDS_FeatureModuleInitializers = MessageBase + 12784, | ||
IDS_FeatureTargetTypedConditional = MessageBase + 12785, | ||
} | ||
|
||
// Message IDs may refer to strings that need to be localized. | ||
|
@@ -334,6 +336,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature) | |
case MessageID.IDS_FeatureRecords: | ||
case MessageID.IDS_FeatureStaticAnonymousFunction: // syntax check | ||
case MessageID.IDS_FeatureModuleInitializers: // semantic check on method attribute | ||
case MessageID.IDS_FeatureDefaultTypeParameterConstraint: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Consider adding a comment if this is not a parsing time check #Closed |
||
return LanguageVersion.Preview; | ||
|
||
// C# 8.0 features. | ||
|
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 is somewhat confusing because
default
constraint isn't involved. #ClosedThere 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.
Added a comment.
In reply to: 456677882 [](ancestors = 456677882)