Skip to content

Suppress nullable conversion warnings in default arguments#51631

Merged
RikkiGibson merged 6 commits intodotnet:mainfrom
RikkiGibson:fix-51622
Mar 10, 2021
Merged

Suppress nullable conversion warnings in default arguments#51631
RikkiGibson merged 6 commits intodotnet:mainfrom
RikkiGibson:fix-51622

Conversation

@RikkiGibson
Copy link
Member

@RikkiGibson RikkiGibson commented Mar 3, 2021

Closes #51622

The issue is basically that the binder creates a bound node for the argument with a conversion whose "isCast" is false. It seems like the nullable walker will try to recreate such conversions with nullable types re-inferred to try and decide if they're valid. We try to re-classify the conversion with the assumption that the conversion must be implicit, since there seemingly is no cast.

In effect, MyEnum? e = MyEnum.Value currently works properly when MyEnum.Value has constant value 0, but but not when the constant value is non-zero. This is because the default argument that gets inserted is of the underlying type converted to the parameter type--MyEnum? e = 0 is allowed, but MyEnum? e = 1 is not. You have to use MyEnum? e = (MyEnum?)1

It's also not enough to just always set isCast: true--this ends up breaking certain tests where flow analysis depends on the values of default arguments due to attributes. So I decided to set it based on whether the default argument conversion that we found is an explicit conversion.

Ultimately, nullable diagnostics are never supposed to be reported on implicit default arguments, including the conversions of such arguments, and that's the only change in this PR that's strictly needed to resolve this bug. However, it also seems reasonable to adjust the creation of default arguments for consistency in the public API.

@ghost ghost added the Area-Compilers label Mar 3, 2021
Base automatically changed from master to main March 3, 2021 23:53
@RikkiGibson RikkiGibson marked this pull request as ready for review March 4, 2021 20:23
@RikkiGibson RikkiGibson requested a review from a team as a code owner March 4, 2021 20:23
@RikkiGibson
Copy link
Member Author

@dotnet/roslyn-compiler Please review

@RikkiGibson
Copy link
Member Author

@dotnet/roslyn-compiler Please review

@jcouv jcouv self-assigned this Mar 9, 2021
defaultValue.Syntax,
defaultValue,
conversion,
isCast: conversion.IsExplicit,
Copy link
Member

Choose a reason for hiding this comment

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

From our offline discussion: is it possible to observe this change?

Copy link
Member Author

Choose a reason for hiding this comment

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

It does not appear to be observable through either public API or through differences in diagnostics.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oddly enough I think the IsImplicit property on the IConversionOperation ends up being true if either the node is compiler generated, or if the conversion is not from a cast

bool isImplicit = boundConversion.WasCompilerGenerated || !boundConversion.ExplicitCastInCode;

Copy link
Member Author

Choose a reason for hiding this comment

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

I made a pass over the usages of 'BoundConversion.IsExplicitCastInCode' and I wasn't able to come up with a scenario where behavior for a default argument would change.

defaultValue,
conversion,
isCast: conversion.IsExplicit,
new ConversionGroup(conversion, parameter.TypeWithAnnotations),
Copy link
Member

Choose a reason for hiding this comment

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

From our offline discussion: consider avoiding this allocation when isCast is false

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

Done with review pass (iteration 5)

@jcouv jcouv added this to the 16.10 milestone Mar 9, 2021
Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 6)

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.

Spurious CS8620 in SDK 5.0.200 (post VS 16.9 update) for nullable enum parameters with non-null default values.

4 participants