Skip to content

Adjust type of out var based on parameter state#36284

Merged
jcouv merged 2 commits intodotnet:masterfrom
jcouv:out-vars
Jun 14, 2019
Merged

Adjust type of out var based on parameter state#36284
jcouv merged 2 commits intodotnet:masterfrom
jcouv:out-vars

Conversation

@jcouv
Copy link
Copy Markdown
Member

@jcouv jcouv commented Jun 10, 2019

This PR fixes the problem with TryGetValue(key, out var value). Previously we would have warned on output assignment to value. Now we adjust the type of var so that there is no warning.

In var x = MaybeNull(y); we use the null-state of the return value to determine the type of var. If the return value is annotated with [MaybeNull], the null-state will be maybe-null even if the inference type arguments for the method are un-annotated, and the type of the var will be annotated.

Similarly, we want the null-state of the out parameters to help determine the type of out vars. So MaybeNull(y, out var x) can result in a var with an annotated type.

Relates to #35816 (list of work items related to nullable annotation attributes)

@jcouv jcouv added this to the 16.2 milestone Jun 10, 2019
@jcouv jcouv self-assigned this Jun 10, 2019
@jaredpar jaredpar mentioned this pull request Jun 10, 2019
23 tasks
@jcouv jcouv modified the milestones: 16.2, 16.2.P4 Jun 12, 2019
ns4 /*T:string?*/ .ToString(); // 6
ns4 = null;

FalseOut(out var s5);
Copy link
Copy Markdown
Member Author

@jcouv jcouv Jun 12, 2019

Choose a reason for hiding this comment

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

out var s5 [](start = 17, length = 10)

📝 This var used to be oblivious (picking its type from the TypeWithAnnotations of the out parameter). But now it gets its type from the null-state of the output value (which is non-null since the parameter is marked as oblivious). #Resolved

@jcouv jcouv marked this pull request as ready for review June 12, 2019 21:55
@jcouv jcouv requested a review from a team as a code owner June 12, 2019 21:55
using System.Diagnostics.CodeAnalysis;
public class Optional<T>
{
public static bool MaybeNullWhenFalse([MaybeNullWhen(false)] string s) => throw null!;
Copy link
Copy Markdown
Member

@RikkiGibson RikkiGibson Jun 12, 2019

Choose a reason for hiding this comment

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

What does this static method do in the test? #Resolved

// ns4 /*T:string?*/ .ToString(); // warn 6
// ns4 /*T:string?*/ .ToString(); // 6
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "ns4").WithLocation(30, 9),
// (35,14): warning CS8600: Converting null literal or possible null value to non-nullable type.
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 12, 2019

Choose a reason for hiding this comment

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

// (35,14): warning CS8600: Converting null literal or possible null value to non-nullable type. [](start = 16, length = 96)

This warning feels unexpected. The goal of the change was to relax the type in some scenarios, but we ended up tightening the type in unrelated scenarios. #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 left a note above to explain this behavior. This is the same behavior we get from a var declaration initialized with a string~. The null-state of the value is not-null, so the var is a string!.
I think this is correct.


In reply to: 293147949 [](ancestors = 293147949)

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.

The null-state of the value is not-null, so the var is a string!. I think this is correct.

I cannot say that I like this behavior.


In reply to: 293634127 [](ancestors = 293634127,293147949)

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 cannot say that I like this behavior.

I agree it doesn't feel great, but I don't have a good idea for an alternative that would make sense.

Just to clarify, do you also dislike the behavior in var x = ...; scenario?
Let's file an issue if you have a suggestion for better behavior.


In reply to: 293894338 [](ancestors = 293894338,293634127,293147949)

using System.Diagnostics.CodeAnalysis;
public class Optional<T>
{
public static bool MaybeNullWhenFalse([MaybeNullWhen(false)] string s) => throw null!;
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 12, 2019

Choose a reason for hiding this comment

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

public static bool MaybeNullWhenFalse([MaybeNullWhen(false)] string s) => throw null!; [](start = 4, length = 86)

This method doesn't look used. #Closed

}

[Fact]
public void MaybeNullWhenFalse_TryGetValue()
Copy link
Copy Markdown
Contributor

@AlekseyTs AlekseyTs Jun 12, 2019

Choose a reason for hiding this comment

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

MaybeNullWhenFalse_TryGetValue [](start = 20, length = 30)

Consider adding similar test for [MaybeNull]. #Closed

@AlekseyTs
Copy link
Copy Markdown
Contributor

AlekseyTs commented Jun 12, 2019

Done with review pass (iteration 1) #Closed

@jcouv
Copy link
Copy Markdown
Member Author

jcouv commented Jun 14, 2019

@AlekseyTs I've resolved or replied to your feedback. Please take another look when you have some time. Thanks

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 2)

@jcouv jcouv merged commit 9e62637 into dotnet:master Jun 14, 2019
@jcouv jcouv deleted the out-vars branch June 14, 2019 17:12
333fred added a commit to 333fred/roslyn that referenced this pull request Jun 18, 2019
…-types

* dotnet/master: (63 commits)
  Fix stack overflow in requesting syntax directives (dotnet#36347)
  crash on ClassifyUpdate for EventFields (dotnet#35962)
  Disable move type when the options service isn't present (dotnet#36334)
  Fix crash where type inference doing method inference needs to drop nullability
  Fix parsing bug in invalid using statements (dotnet#36428)
  Do not suggest or diagnose use compound assignment when right hand of binary operator is a throw expression
  Add option to emit nullable metadata for public members only (dotnet#36398)
  Added null checks on F# external access services (dotnet#36469)
  Deal with discovering extra .editorconfig files
  Re-enable MSBuildWorkspaceTests.TestEditorConfigDiscovery
  Add support to VisualStudioMSBuildInstalled to support minimum versions
  Fix configuration of accessibilities in editorconfig
  Shorten a resource ID
  Revert "Extract the RDT implementation for Misc files and VS open file tracker"
  Add nullability support to use local function
  Add EditorFeatures.WPF dependency to F# ExternalAccess
  Ensure NullableWalker.AsMemberOfType locates the right new container for the member. (dotnet#36406)
  Replace `dynamic` with `object` when substituting constraints. (dotnet#36379)
  Add some string descriptions
  Adjust type of out var based on parameter state (dotnet#36284)
  ...
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