Skip to content
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

Suppress nullable conversion warnings in default arguments #51631

Merged
merged 6 commits into from
Mar 10, 2021

Conversation

RikkiGibson
Copy link
Contributor

@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.

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
Contributor Author

@dotnet/roslyn-compiler Please review

@RikkiGibson
Copy link
Contributor 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
Contributor 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
Contributor 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
Contributor 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
Contributor 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
4 participants