Report passing a maybe-null int? to [DisallowNull] parameter#36263
Report passing a maybe-null int? to [DisallowNull] parameter#36263jcouv merged 4 commits intodotnet:masterfrom
Conversation
| <value>Argument cannot be used as an output for parameter due to differences in the nullability of reference types.</value> | ||
| </data> | ||
| <data name="WRN_NullDisallowedInAssignment" xml:space="preserve"> | ||
| <value>A possible null value may not be passed to a target marked with the [DisallowNull] attribute</value> |
There was a problem hiding this comment.
Would it make sense to make the message more descriptive and include information for the parameter and the method as we do in other similar warnings? #Closed
There was a problem hiding this comment.
The reason I used general terms is because we'll use the same message for passing a maybe-null value to a property or field marked with [DisallowNull].
In reply to: 292590685 [](ancestors = 292590685)
| <data name="WRN_NullabilityMismatchInArgumentForOutput_Title" xml:space="preserve"> | ||
| <value>Argument cannot be used as an output for parameter due to differences in the nullability of reference types.</value> | ||
| </data> | ||
| <data name="WRN_NullDisallowedInAssignment" xml:space="preserve"> |
There was a problem hiding this comment.
WRN_NullDisallowedInAssignment [](start = 14, length = 30)
Consider using for specific name, reflecting that it is about DisallowNullAttribute. #Closed
| WRN_NullReferenceIterationVariable = 8606, | ||
| // Unused 8607-8608 | ||
| WRN_NullDisallowedInAssignment = 8607, | ||
| // Unused 8608-8608 |
There was a problem hiding this comment.
8608-8608 [](start = 18, length = 9)
Minor, this isn't really a range any more. #Closed
|
|
||
| private void CheckDisallowedNullAssignment(TypeWithState state, TypeWithAnnotations type, FlowAnalysisAnnotations annotations, Location location) | ||
| { | ||
| if (type.IsNullableType() && state.MayBeNull && ((annotations & FlowAnalysisAnnotations.DisallowNull) != 0)) |
There was a problem hiding this comment.
((annotations & FlowAnalysisAnnotations.DisallowNull) != 0) [](start = 60, length = 59)
Would it make sense to check this first? #Closed
|
|
||
| private void CheckDisallowedNullAssignment(TypeWithState state, TypeWithAnnotations type, FlowAnalysisAnnotations annotations, Location location) | ||
| { | ||
| if (type.IsNullableType() && state.MayBeNull && ((annotations & FlowAnalysisAnnotations.DisallowNull) != 0)) |
There was a problem hiding this comment.
type.IsNullableType() [](start = 16, length = 21)
Do we want to cover type parameters constrained to a nullable value type? This check will not cover them. Please add a test regardless. #Closed
There was a problem hiding this comment.
I didn't understand.
I don't think we can constrain a type parameter to a nullable value type: where T : U? where U : struct is an error. (error CS0701: 'U?' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter.)
In reply to: 292606714 [](ancestors = 292606714)
There was a problem hiding this comment.
There was a problem hiding this comment.
I don't see a unit-test for that scenario.
In reply to: 292634369 [](ancestors = 292634369,292632259,292606714)
| @"using System.Runtime.CompilerServices; | ||
| class Program | ||
| { | ||
| static void F5<T>([DisallowNull]ref T? t) where T : struct { } |
There was a problem hiding this comment.
ref [](start = 36, length = 3)
Consider covering in as well. #Closed
|
Done with review pass (iteration 2) #Closed |
| Debug.Assert(!this.IsConditionalState); | ||
| } | ||
|
|
||
| private void CheckDisallowedNullAssignment(TypeWithState state, TypeWithAnnotations type, FlowAnalysisAnnotations annotations, Location location) |
There was a problem hiding this comment.
Does it make sense to make this a local function? #ByDesign
There was a problem hiding this comment.
I expect to use the method for checking on scenario when assigning to fields and properties too.
In reply to: 292627658 [](ancestors = 292627658)
| } | ||
|
|
||
| [Fact, WorkItem(36009, "https://github.com/dotnet/roslyn/issues/36009")] | ||
| public void DisallowNull_ByValParameter_NullableValueTypeViaConstraint() |
There was a problem hiding this comment.
DisallowNull_ByValParameter_NullableValueTypeViaConstraint [](start = 20, length = 58)
I am not sure what are we trying to test here, struct constraint doesn't allow nullable value types and U is a nullable value type from constraints. #Closed
|
Done with review pass (iteration 3) #Closed |
|
Thanks @AlekseyTs @333fred Do you have any other feedback? |
We should warn for passing a maybe-null value to a
[DisallowNull]parameter that has a nullable value type.Note: when implementing attributes on fields and properties, we'll have to do the same, since the check was not folded into
VisitConversionorReportNullableAssignmentIfNecessary.Relates to #35816 (attributes work)