Skip to content

Report passing a maybe-null int? to [DisallowNull] parameter#36263

Merged
jcouv merged 4 commits intodotnet:masterfrom
jcouv:disallow-nullable
Jun 12, 2019
Merged

Report passing a maybe-null int? to [DisallowNull] parameter#36263
jcouv merged 4 commits intodotnet:masterfrom
jcouv:disallow-nullable

Conversation

@jcouv
Copy link
Copy Markdown
Member

@jcouv jcouv commented Jun 8, 2019

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 VisitConversion or ReportNullableAssignmentIfNecessary.

Relates to #35816 (attributes work)

@jcouv jcouv added this to the 16.2.P3 milestone Jun 8, 2019
@jcouv jcouv self-assigned this Jun 8, 2019
@jinujoseph jinujoseph modified the milestones: 16.2.P3, 16.2 Jun 9, 2019
@jcouv jcouv force-pushed the disallow-nullable branch from 18fcc0a to 68dd9f9 Compare June 10, 2019 19:16
@jcouv jcouv marked this pull request as ready for review June 10, 2019 19:34
@jcouv jcouv requested a review from a team as a code owner June 10, 2019 19:34
@jcouv jcouv force-pushed the disallow-nullable branch from 7147f1b to c7725d6 Compare June 10, 2019 22:53
@jaredpar jaredpar mentioned this pull request Jun 10, 2019
23 tasks
<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>
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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">
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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))
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

((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))
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chuck gave me some hint how to do that.


In reply to: 292632259 [](ancestors = 292632259,292606714)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 { }
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ref [](start = 36, length = 3)

Consider covering in as well. #Closed

@AlekseyTs
Copy link
Copy Markdown
Contributor

AlekseyTs commented Jun 11, 2019

Done with review pass (iteration 2) #Closed

Debug.Assert(!this.IsConditionalState);
}

private void CheckDisallowedNullAssignment(TypeWithState state, TypeWithAnnotations type, FlowAnalysisAnnotations annotations, Location location)
Copy link
Copy Markdown
Member

@333fred 333fred Jun 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to make this a local function? #ByDesign

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@AlekseyTs
Copy link
Copy Markdown
Contributor

AlekseyTs commented Jun 11, 2019

Done with review pass (iteration 3) #Closed

@jcouv jcouv force-pushed the disallow-nullable branch from 9b99ed7 to b49632e Compare June 12, 2019 00:28
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (iteration 4)

@jcouv
Copy link
Copy Markdown
Member Author

jcouv commented Jun 12, 2019

Thanks @AlekseyTs

@333fred Do you have any other feedback?

@jcouv jcouv merged commit 56dde62 into dotnet:master Jun 12, 2019
@jcouv jcouv deleted the disallow-nullable branch June 12, 2019 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants