dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.99k stars 4.03k forks source link

Report WRN_NullabilityMismatchInArgument rather than WRN_NullabilityMismatchInAssignment for tuples used as the arguments #29966

Open AlekseyTs opened 6 years ago

AlekseyTs commented 6 years ago
        [Fact]
        public void Conversions_ImplicitTupleLiteral_01()
        {
            var source =
@"#pragma warning disable 0219
interface I<T> { }
interface IIn<in T> { }
interface IOut<out T> { }
class A<T> : I<T> { }
class B<T> : IIn<T> { }
class C<T> : IOut<T> { }
static class E
{
    static void F1(string x, string? y)
    {
        (string, string) t1 = (x, y); // 1
        (string?, string?) u1 = (x, y);
        (object, object) v1 = (x, y); // 2
        (object?, object?) w1 = (x, y);
        F1A((x, y)); // 3
        F1B((x, y));
        F1C((x, y)); // 4
        F1D((x, y));
    }
    static void F1A((string, string) t) { }
    static void F1B((string?, string?) t) { }
    static void F1C((object, object) t) { }
    static void F1D((object?, object?) t) { }
    static void F2(A<object> x, A<object?> y)
    {
        (A<object>, A<object>) t2 = (x, y); // 5
        (A<object?>, A<object?>) u2 = (x, y); // 6
        (I<object>, I<object>) v2 = (x, y); // 7
        (I<object?>, I<object?>) w2 = (x, y); // 8
        F2A((x, y)); // 9
        F2B((x, y)); // 10
        F2C((x, y)); // 11
        F2D((x, y)); // 12
    }
    static void F2A((A<object>, A<object>) t) { }
    static void F2B((A<object?>, A<object?>) t) { }
    static void F2C((I<object>, I<object>) t) { }
    static void F2D((I<object?>, I<object?>) t) { }
    static void F3(B<object> x, B<object?> y)
    {
        (B<object>, B<object>) t3 = (x, y); // 13
        (B<object?>, B<object?>) u3 = (x, y); // 14
        (IIn<object>, IIn<object>) v3 = (x, y);
        (IIn<object?>, IIn<object?>) w3 = (x, y); // 15
        F3A((x, y));
        F3B((x, y)); // 16
    }
    static void F3A((IIn<object>, IIn<object>) t) { }
    static void F3B((IIn<object?>, IIn<object?>) t) { }
    static void F4(C<object> x, C<object?> y)
    {
        (C<object>, C<object>) t4 = (x, y); // 17
        (C<object?>, C<object?>) u4 = (x, y); // 18
        (IOut<object>, IOut<object>) v4 = (x, y); // 19
        (IOut<object?>, IOut<object?>) w4 = (x, y);
        F4A((x, y)); // 20
        F4B((x, y));
    }
    static void F4A((IOut<object>, IOut<object>) t) { }
    static void F4B((IOut<object?>, IOut<object?>) t) { }
    static void F5<T, U>(U u) where U : T
    {
        (T,  T) t5 = (u, default(T));
        (object, object) v5 = (default(T), u); // 21
        (object?, object?) w5 = (default(T), u);
    }
}";
            var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition });
            // PROTOTYPE(NullableReferenceTypes): Report WRN_NullabilityMismatchInArgument rather than ...Assignment.
            comp.VerifyDiagnostics(
                // (12,31): warning CS8619: Nullability of reference types in value of type '(string x, string? y)' doesn't match target type '(string, string)'.
                //         (string, string) t1 = (x, y); // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(x, y)").WithArguments("(string x, string? y)", "(string, string)").WithLocation(12, 31),
                // (14,31): warning CS8619: Nullability of reference types in value of type '(object x, object? y)' doesn't match target type '(object, object)'.
                //         (object, object) v1 = (x, y); // 2
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(x, y)").WithArguments("(object x, object? y)", "(object, object)").WithLocation(14, 31),
                // (16,13): warning CS8620: Nullability of reference types in argument of type '(string x, string? y)' doesn't match target type '(string, string)' for parameter 't' in 'void E.F1A((string, string) t)'.
                //         F1A((x, y)); // 3
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "(x, y)").WithArguments("(string x, string? y)", "(string, string)", "t", "void E.F1A((string, string) t)").WithLocation(16, 13),
                // (18,13): warning CS8620: Nullability of reference types in argument of type '(object x, object? y)' doesn't match target type '(object, object)' for parameter 't' in 'void E.F1C((object, object) t)'.
                //         F1C((x, y)); // 4
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "(x, y)").WithArguments("(object x, object? y)", "(object, object)", "t", "void E.F1C((object, object) t)").WithLocation(18, 13),
                // (27,37): warning CS8619: Nullability of reference types in value of type '(A<object> x, A<object?> y)' doesn't match target type '(A<object>, A<object>)'.
                //         (A<object>, A<object>) t2 = (x, y); // 5
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(x, y)").WithArguments("(A<object> x, A<object?> y)", "(A<object>, A<object>)").WithLocation(27, 37),
                // (28,39): warning CS8619: Nullability of reference types in value of type '(A<object> x, A<object?> y)' doesn't match target type '(A<object?>, A<object?>)'.
                //         (A<object?>, A<object?>) u2 = (x, y); // 6
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(x, y)").WithArguments("(A<object> x, A<object?> y)", "(A<object?>, A<object?>)").WithLocation(28, 39),
                // (29,41): warning CS8619: Nullability of reference types in value of type 'A<object?>' doesn't match target type 'I<object>'.
                //         (I<object>, I<object>) v2 = (x, y); // 7
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "y").WithArguments("A<object?>", "I<object>").WithLocation(29, 41),
                // (30,40): warning CS8619: Nullability of reference types in value of type 'A<object>' doesn't match target type 'I<object?>'.
                //         (I<object?>, I<object?>) w2 = (x, y); // 8
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x").WithArguments("A<object>", "I<object?>").WithLocation(30, 40),
                // (31,13): warning CS8620: Nullability of reference types in argument of type '(A<object> x, A<object?> y)' doesn't match target type '(A<object>, A<object>)' for parameter 't' in 'void E.F2A((A<object>, A<object>) t)'.
                //         F2A((x, y)); // 9
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "(x, y)").WithArguments("(A<object> x, A<object?> y)", "(A<object>, A<object>)", "t", "void E.F2A((A<object>, A<object>) t)").WithLocation(31, 13),
                // (32,13): warning CS8620: Nullability of reference types in argument of type '(A<object> x, A<object?> y)' doesn't match target type '(A<object?>, A<object?>)' for parameter 't' in 'void E.F2B((A<object?>, A<object?>) t)'.
                //         F2B((x, y)); // 10
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "(x, y)").WithArguments("(A<object> x, A<object?> y)", "(A<object?>, A<object?>)", "t", "void E.F2B((A<object?>, A<object?>) t)").WithLocation(32, 13),
                // (33,17): warning CS8619: Nullability of reference types in value of type 'A<object?>' doesn't match target type 'I<object>'.
                //         F2C((x, y)); // 11
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "y").WithArguments("A<object?>", "I<object>").WithLocation(33, 17),
                // (34,14): warning CS8619: Nullability of reference types in value of type 'A<object>' doesn't match target type 'I<object?>'.
                //         F2D((x, y)); // 12
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x").WithArguments("A<object>", "I<object?>").WithLocation(34, 14),
                // (42,37): warning CS8619: Nullability of reference types in value of type '(B<object> x, B<object?> y)' doesn't match target type '(B<object>, B<object>)'.
                //         (B<object>, B<object>) t3 = (x, y); // 13
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(x, y)").WithArguments("(B<object> x, B<object?> y)", "(B<object>, B<object>)").WithLocation(42, 37),
                // (43,39): warning CS8619: Nullability of reference types in value of type '(B<object> x, B<object?> y)' doesn't match target type '(B<object?>, B<object?>)'.
                //         (B<object?>, B<object?>) u3 = (x, y); // 14
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(x, y)").WithArguments("(B<object> x, B<object?> y)", "(B<object?>, B<object?>)").WithLocation(43, 39),
                // (45,44): warning CS8619: Nullability of reference types in value of type 'B<object>' doesn't match target type 'IIn<object?>'.
                //         (IIn<object?>, IIn<object?>) w3 = (x, y); // 15
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x").WithArguments("B<object>", "IIn<object?>").WithLocation(45, 44),
                // (47,14): warning CS8619: Nullability of reference types in value of type 'B<object>' doesn't match target type 'IIn<object?>'.
                //         F3B((x, y)); // 16
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x").WithArguments("B<object>", "IIn<object?>").WithLocation(47, 14),
                // (53,37): warning CS8619: Nullability of reference types in value of type '(C<object> x, C<object?> y)' doesn't match target type '(C<object>, C<object>)'.
                //         (C<object>, C<object>) t4 = (x, y); // 17
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(x, y)").WithArguments("(C<object> x, C<object?> y)", "(C<object>, C<object>)").WithLocation(53, 37),
                // (54,39): warning CS8619: Nullability of reference types in value of type '(C<object> x, C<object?> y)' doesn't match target type '(C<object?>, C<object?>)'.
                //         (C<object?>, C<object?>) u4 = (x, y); // 18
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(x, y)").WithArguments("(C<object> x, C<object?> y)", "(C<object?>, C<object?>)").WithLocation(54, 39),
                // (55,47): warning CS8619: Nullability of reference types in value of type 'C<object?>' doesn't match target type 'IOut<object>'.
                //         (IOut<object>, IOut<object>) v4 = (x, y); // 19
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "y").WithArguments("C<object?>", "IOut<object>").WithLocation(55, 47),
                // (57,17): warning CS8619: Nullability of reference types in value of type 'C<object?>' doesn't match target type 'IOut<object>'.
                //         F4A((x, y)); // 20
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "y").WithArguments("C<object?>", "IOut<object>").WithLocation(57, 17),
                // (65,31): warning CS8619: Nullability of reference types in value of type '(object?, object? u)' doesn't match target type '(object, object)'.
                //         (object, object) v5 = (default(T), u); // 21
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(default(T), u)").WithArguments("(object?, object? u)", "(object, object)").WithLocation(65, 31));
        }

Examples:

                // (33,17): warning CS8619: Nullability of reference types in value of type 'A<object?>' doesn't match target type 'I<object>'.
                //         F2C((x, y)); // 11
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "y").WithArguments("A<object?>", "I<object>").WithLocation(33, 17),
                // (34,14): warning CS8619: Nullability of reference types in value of type 'A<object>' doesn't match target type 'I<object?>'.
                //         F2D((x, y)); // 12
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x").WithArguments("A<object>", "I<object?>").WithLocation(34, 14),
                // (47,14): warning CS8619: Nullability of reference types in value of type 'B<object>' doesn't match target type 'IIn<object?>'.
                //         F3B((x, y)); // 16
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x").WithArguments("B<object>", "IIn<object?>").WithLocation(47, 14),
                // (57,17): warning CS8619: Nullability of reference types in value of type 'C<object?>' doesn't match target type 'IOut<object>'.
                //         F4A((x, y)); // 20
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "y").WithArguments("C<object?>", "IOut<object>").WithLocation(57, 17),
AlekseyTs commented 6 years ago
        [Fact]
        public void Conversions_ImplicitTupleLiteral_ExtensionThis()
        {
            var source =
@"interface I<T> { }
interface IIn<in T> { }
interface IOut<out T> { }
class A<T> : I<T> { }
class B<T> : IIn<T> { }
class C<T> : IOut<T> { }
static class E
{
    static void F1(string x, string? y)
    {
        (x, y).F1A(); // 1
        (x, y).F1B();
    }
    static void F1A(this (object, object) t) { }
    static void F1B(this (object?, object?) t) { }
    static void F2(A<object> x, A<object?> y)
    {
        (x, y).F2A(); // 2
        (x, y).F2B(); // 3
    }
    static void F2A(this (I<object>, I<object>) t) { }
    static void F2B(this (I<object?>, I<object?>) t) { }
    static void F3(B<object> x, B<object?> y)
    {
        (x, y).F3A();
        (x, y).F3B(); // 4
    }
    static void F3A(this (IIn<object>, IIn<object>) t) { }
    static void F3B(this (IIn<object?>, IIn<object?>) t) { }
    static void F4(C<object> x, C<object?> y)
    {
        (x, y).F4A(); // 5
        (x, y).F4B();
    }
    static void F4A(this (IOut<object>, IOut<object>) t) { }
    static void F4B(this (IOut<object?>, IOut<object?>) t) { }
}";
            var comp = CreateCompilation(new[] { source, NonNullTypesTrue, NonNullTypesAttributesDefinition });
            // PROTOTYPE(NullableReferenceTypes): Report WRN_NullabilityMismatchInArgument rather than ...Assignment.
            comp.VerifyDiagnostics(
                // (11,9): warning CS8620: Nullability of reference types in argument of type '(object x, object? y)' doesn't match target type '(object, object)' for parameter 't' in 'void E.F1A((object, object) t)'.
                //         (x, y).F1A(); // 1
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgument, "(x, y)").WithArguments("(object x, object? y)", "(object, object)", "t", "void E.F1A((object, object) t)").WithLocation(11, 9),
                // (18,13): warning CS8619: Nullability of reference types in value of type 'A<object?>' doesn't match target type 'I<object>'.
                //         (x, y).F2A(); // 2
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "y").WithArguments("A<object?>", "I<object>").WithLocation(18, 13),
                // (19,10): warning CS8619: Nullability of reference types in value of type 'A<object>' doesn't match target type 'I<object?>'.
                //         (x, y).F2B(); // 3
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x").WithArguments("A<object>", "I<object?>").WithLocation(19, 10),
                // (26,10): warning CS8619: Nullability of reference types in value of type 'B<object>' doesn't match target type 'IIn<object?>'.
                //         (x, y).F3B(); // 4
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "x").WithArguments("B<object>", "IIn<object?>").WithLocation(26, 10),
                // (32,13): warning CS8619: Nullability of reference types in value of type 'C<object?>' doesn't match target type 'IOut<object>'.
                //         (x, y).F4A(); // 5
                Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "y").WithArguments("C<object?>", "IOut<object>").WithLocation(32, 13));
        }