-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Fix inference with ref parameter with maybe-null value #47952
Conversation
4d9a725
to
9b2faa1
Compare
Tagging @stephentoub @jkotas. But, due to another open issue with For example, calls to
I believe those are uncommon (the location argument would typically be maybe-null). Any other generic API call with a |
|
||
class C | ||
{ | ||
static void X1<T>([NotNullIfNotNull(""value"")] ref T location, T value) where T : class? { } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How did your change affect this scenario? I can get how before we inferred a double[]
type argument and now we infer a double[]?
type argument, but how did that result in the postcondition for the NotNullIfNotNullAttribute starting to be respected? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We used to produce a warning on ref f1
for assigning maybe-null value inbound to the first parameter (which was inferred as double[]!
.
For ref f2
we now produce a diagnostic on the outbound assignment from parameter double[]?
to local typed double[]!
.
In reply to: 493893383 [](ancestors = 493893383)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes complete sense now, thanks!
@jcouv, have you tried building dotnet/runtime? Does this introduce any new warnings-as-error as part of its build? Thanks. |
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
Show resolved
Hide resolved
{ | ||
double[] bar = new double[3]; | ||
X1(ref f1, bar); | ||
X2(ref f2, bar); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add // 1
comments here to help identify which diagnostic lines up where?
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
Outdated
Show resolved
Hide resolved
Testing this change in |
The VS validation build has two new warnings because of this change:
BuildProjectScannerService.cs Those are consequences of the known issue with FYI @dibarbet I'll add a test to this PR to illustrate that scenario. |
@jcouv would you mind if I updated your validation PR (I assume https://devdiv.visualstudio.com/DevDiv/_git/VS/pullrequest/277093?_a=overview) to include the suggested fixes? That way I can be sure cloud build is passing with them and I can easily cherry-pick the commit over to the proper insertion |
@dibarbet Thanks. I've pushed two commits to the validation PR and will ping you once it is green. |
Here are a few scenarios that we should try to make work in a future PR. I think #nullable enable
public class C {
public void M1<T>(ref T t1, T t2)
{
t1 = t2;
}
public void M2()
{
string? s = "a";
M1(ref s, null);
s.ToString(); // should warn
}
public void M3()
{
string? s1 = "a";
string? s2 = null;
M1(ref s1, s2);
s1.ToString(); // should warn
}
public void M4()
{
string? s = "a";
M1(ref s, "b");
s.ToString(); // should not warn
}
} |
@jcouv forgot to mention - to get a passing cloudbuild you may need the two extra commits from this PR |
@dibarbet Thanks. I indeed had to add the two commits from that other PR to get the build to pass. |
Previously, the L-value of a
ref
argument would contribute its type+nullability. Now we're using the R-value.Fixes #47663
Fixes #35534
Note that the inference in some scenario becomes a bit worse (for example with
CompareExchange
) when there is aref
argument andnull
. There is a known issue withnull
not contributing nullability to method type inference.We could discuss whether to hold off this change until the issue with
null
is fixed.I think the current change can be taken as-is, because (1) they involve having a nullable but not-null
ref
, which is uncommon forCompareExchange
, and (2) they can be mitigated with explicit type parameters.