-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Incorrect "Nullability doesn't match the target delegate" when tuple element names don't explicitly match #74493
Comments
The problem goes further than nullability. An error type is getting created by the method type inferrer for the ToDictionary call. This can even be seen in the IDE: Versus for exact name matches on the tuple elements: There are no diagnostics or emit issues in the final compilation, though. This is the cause of the detection of a "nullability mismatch." |
I looked into this further, and found that the nullability phase might be getting something right. I'm not sure this code should be compiling. If you insert an object cast, the code stops compiling because the tuple element names conflict and are discarded, and #nullable disable
class C
{
void M((string Name, object Value)[] parameters)
{
_ = parameters.Append(("A", (object)"A")).ToDictionary(
tuple => tuple.Name, // '(string, object)' does not contain a definition for 'Name' [...]
tuple => tuple.Value); // '(string, object)' does not contain a definition for 'Value' [...]
}
} Alternatively to adding the object cast, you could change the parameters to So, potentially, I don't think the original example should be compiling at all. The sad part is I know I've taken a dependency on this "only consider names of the receiver's tuple" behavior, over and over, with these LINQ methods. What's happening is that when the tuple types aren't equal ( When the nullability pass gets here, it does call MergeAndReplaceIfStillCandidate, which removes tuple element names which conflict between the two arguments to Append (impl, impl). |
@jcouv Is this connected to #27961? roslyn/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs Lines 7748 to 7754 in 0cd65d1
|
"Inference should be based on unconverted arguments" seems like it sums up the exact discrepancy that this issue was about. The arguments being passed back in to method type inference have already been target-typed using the result of the prior inference for the same type parameter. This explains why the inference invoked by the nullability pass is evaluating to true at https://github.com/dotnet/roslyn/blob/main/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MethodTypeInference.cs#L3299 and is therefore removing conflicting tuple element names. |
Perhaps a fix could be to do something like what was done for lambdas and collection expressions in roslyn/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs Lines 7776 to 7797 in 0cd65d1
|
Yes, that sounds right. The infrastructure for target-typed expressions has evolved over time and I think that collection expressions are the latest example, so may be a good example to follow. |
Version Used: 17.11.0 Preview 3.0
The following code erroneously causes this warning to appear for each lambda in the Error List and at the command line, though squiggles are not shown:
If you name the elements in the tuple expression to exactly match the tuple element names in the collection, the warning goes away.
For each element where a name is missing or does not exactly match, a nullability warning returns.
The text was updated successfully, but these errors were encountered: