// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable

using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics
{
    public class UninitializedNonNullableFieldTests : CSharpTestBase
    {
        [Fact]
        public void UninitializedEvents()
        {
            var src = @"
using System;
class C
{
    public event Action<object?> E1;
    public event Action<object?> E2 { add { } remove { } }
#pragma warning disable 0414
    public event Action<object?> E3 = null!;
    public event Action<object?>? E4 = null;
#pragma warning restore 0414
#pragma warning disable 0626
    public extern event Action<object?> E5;
#pragma warning restore 0626

    internal C()
    {
    }

    internal C(Action<object?> e)
    {
        E1 = e;
        E2 += e;
    }

    internal C(object o)
    {
        E1 += p => {};
        E2 += p => {};
    }
}";
            var comp = CreateCompilation(src, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (15,14): warning CS8618: Non-nullable event 'E1' is uninitialized. Consider declaring the event as nullable.
                //     internal C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("event", "E1").WithLocation(15, 14));
        }

        [Fact]
        public void Event_InitialState()
        {
            var src = @"
using System;
class C
{
    public event Action E1 = () => { };
    public event Action E2;
    internal C()
    {
        E1.Invoke();
        E2.Invoke(); // 1
    }
}";
            var comp = CreateCompilation(src, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (10,9): warning CS8602: Dereference of a possibly null reference.
                //         E2.Invoke(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "E2").WithLocation(10, 9));
        }

        [Fact]
        public void NoExplicitConstructors_CSharp7_01()
        {
            var source =
@"class C
{
    internal object F;
    static object G;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7);
            comp.VerifyDiagnostics(
                // (3,21): warning CS0649: Field 'C.F' is never assigned to, and will always have its default value null
                //     internal object F;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F").WithArguments("C.F", "null").WithLocation(3, 21),
                // (4,19): warning CS0169: The field 'C.G' is never used
                //     static object G;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "G").WithArguments("C.G").WithLocation(4, 19));
        }

        [Fact]
        public void NoExplicitConstructors_CSharp7_02()
        {
            var source =
@"class C
{
#nullable enable
    internal object F;
    static object G;
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7, skipUsesIsNullable: true);
            comp.VerifyDiagnostics(
                // (3,2): error CS8107: Feature 'nullable reference types' is not available in C# 7.0. Please use language version 8.0 or greater.
                // #nullable enable
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "nullable").WithArguments("nullable reference types", "8.0").WithLocation(3, 2),
                // (4,21): warning CS0649: Field 'C.F' is never assigned to, and will always have its default value null
                //     internal object F;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F").WithArguments("C.F", "null").WithLocation(4, 21),
                // (5,19): warning CS0169: The field 'C.G' is never used
                //     static object G;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "G").WithArguments("C.G").WithLocation(5, 19));
        }

        [Fact]
        public void NoExplicitConstructors()
        {
            var source =
@"class C
{
    internal object F;
    static object G;
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (3,21): warning CS8618: Non-nullable field 'F' is uninitialized. Consider declaring the field as nullable.
                //     internal object F;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F").WithArguments("field", "F").WithLocation(3, 21),
                // (3,21): warning CS0649: Field 'C.F' is never assigned to, and will always have its default value null
                //     internal object F;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F").WithArguments("C.F", "null").WithLocation(3, 21),
                // (4,19): warning CS8618: Non-nullable field 'G' is uninitialized. Consider declaring the field as nullable.
                //     static object G;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "G").WithArguments("field", "G").WithLocation(4, 19),
                // (4,19): warning CS0169: The field 'C.G' is never used
                //     static object G;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "G").WithArguments("C.G").WithLocation(4, 19));
        }

        [Fact]
        public void ExplicitConstructors_Disabled_01()
        {
            var source =
@"#pragma warning disable 169, 649
#nullable enable
class C
{
    internal object F;
    static object G;
    static C() { }
#nullable disable
    C() { }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,12): warning CS8618: Non-nullable field 'G' is uninitialized. Consider declaring the field as nullable.
                //     static C() { }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "G").WithLocation(7, 12));
        }

        [Fact]
        public void ExplicitConstructors_Disabled_02()
        {
            var source =
@"#pragma warning disable 169, 649
#nullable enable
class C
{
    internal object F;
    static object G;
    C() { }
#nullable disable
    static C() { }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (7,5): warning CS8618: Non-nullable field 'F' is uninitialized. Consider declaring the field as nullable.
                //     C() { }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F").WithLocation(7, 5));
        }

        [Fact]
        public void ExplicitConstructors_Disabled_03()
        {
            var source =
@"#pragma warning disable 169, 649
#nullable disable
class C
{
    internal object F;
    static object G;
#nullable enable
    C() { }
    static C() { }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void Constants()
        {
            var source =
@"class C
{
    private const object? C1 = null;
    internal const object C2 = null!;
    protected const string? C3 = """";
    public const string C4 = """";
}
struct S
{
    internal const string? C5 = null;
    private const string C6 = null!;
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable());
            comp.VerifyDiagnostics();
        }

        [Fact, WorkItem(29849, "https://github.com/dotnet/roslyn/issues/29849")]
        public void UnconstrainedGenericType()
        {
            var source =
@"internal class C<T> where T : new()
{
    internal T F1;
    internal T F2 = new T();
    internal T F3 = default;
    internal T F4 = default(T);
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (3,16): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     internal T F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(3, 16),
                // (3,16): warning CS0649: Field 'C<T>.F1' is never assigned to, and will always have its default value 
                //     internal T F1;
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F1").WithArguments("C<T>.F1", "").WithLocation(3, 16),
                // (5,21): warning CS8601: Possible null reference assignment.
                //     internal T F3 = default;
                Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "default").WithLocation(5, 21),
                // (6,21): warning CS8601: Possible null reference assignment.
                //     internal T F4 = default(T);
                Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "default(T)").WithLocation(6, 21));
        }

        [Fact]
        public void ReadWriteFields_DefaultConstructor()
        {
            var source =
@"class C
{
#pragma warning disable 0169
#pragma warning disable 0649
    private object F1;
    internal object? F2;
    internal object?[] F3;
    private object[]? F4;
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (5,20): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     private object F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(5, 20),
                // (7,24): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     internal object?[] F3;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F3").WithArguments("field", "F3").WithLocation(7, 24));
        }

        [Fact]
        public void ReadWriteFields_ExplicitConstructors()
        {
            var source =
@"class C
{
    internal object F1;
    private object? F2;
    private object?[] F3;
    internal object[]? F4;
    internal C()
    {
    }
    internal C(object o)
    {
        F1 = o;
        F3 = new[] { o, null };
    }
    internal C(object x, object y)
    {
        F2 = x;
        F4 = new[] { x, y };
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (7,14): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     internal C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F3").WithLocation(7, 14),
                // (7,14): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     internal C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F1").WithLocation(7, 14),
                // (15,14): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     internal C(object x, object y)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F3").WithLocation(15, 14),
                // (15,14): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     internal C(object x, object y)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F1").WithLocation(15, 14));
        }

        [Fact]
        public void ReadOnlyFields_DefaultConstructor()
        {
            var source =
@"class C
{
#pragma warning disable 0169
#pragma warning disable 0649
    private readonly object F1;
    internal readonly object? F2;
    internal readonly object?[] F3;
    private readonly object[]? F4;
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (5,29): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     private readonly object F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(5, 29),
                // (7,33): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     internal readonly object?[] F3;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F3").WithArguments("field", "F3").WithLocation(7, 33));
        }

        [Fact]
        public void ReadOnlyFields_ExplicitConstructors()
        {
            var source =
@"class C
{
    internal readonly object F1;
    private readonly object? F2;
    private readonly object?[] F3;
    internal readonly object[]? F4;
    internal C()
    {
    }
    internal C(object o)
    {
        F1 = o;
        F3 = new[] { o, null };
    }
    internal C(object x, object y)
    {
        F2 = x;
        F4 = new[] { x, y };
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (7,14): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     internal C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F3").WithLocation(7, 14),
                // (7,14): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     internal C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F1").WithLocation(7, 14),
                // (15,14): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     internal C(object x, object y)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F3").WithLocation(15, 14),
                // (15,14): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     internal C(object x, object y)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F1").WithLocation(15, 14));
        }

        [Fact]
        public void FieldInitializers_DefaultConstructor()
        {
            var source =
@"class C
{
    private object F1 = new object();
    internal object? F2 = new object();
    internal object?[] F3 = new [] { new object(), null };
    private object[]? F4 = new [] { new object() };
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [Fact]
        [WorkItem(34668, "https://github.com/dotnet/roslyn/issues/34668")]
        public void StaticFields_DefaultConstructor_NoInitializer_Field()
        {
            var source =
@"class C
{
#pragma warning disable 0169
    private static object F;
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (4,27): warning CS8618: Non-nullable field 'F' is uninitialized. Consider declaring the field as nullable.
                //     private static object F;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F").WithArguments("field", "F").WithLocation(4, 27));
        }

        [Fact]
        [WorkItem(34668, "https://github.com/dotnet/roslyn/issues/34668")]
        public void StaticFields_DefaultConstructor_NoInitializer_Property()
        {
            var source =
@"class C
{
    private static object P { get; set; }
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (3,27): warning CS8618: Non-nullable property 'P' is uninitialized. Consider declaring the property as nullable.
                //     private static object P { get; set; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P").WithArguments("property", "P").WithLocation(3, 27));
        }

        [Fact]
        [WorkItem(34668, "https://github.com/dotnet/roslyn/issues/34668")]
        public void StaticFields_DefaultConstructor_NoInitializer_Event()
        {
            var source =
@"delegate void D();
#pragma warning disable 0067
class C
{
    private static event D E;
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (5,28): warning CS8618: Non-nullable event 'E' is uninitialized. Consider declaring the event as nullable.
                //     private static event D E;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "E").WithArguments("event", "E").WithLocation(5, 28));
        }

        [Fact]
        [WorkItem(34668, "https://github.com/dotnet/roslyn/issues/34668")]
        public void StaticFields_DefaultConstructor()
        {
            var source =
@"class C
{
#pragma warning disable 0169
    private static object F1;
    private static object F2 = new object();
    private readonly static object F3;
    private readonly static object F4 = new object();
    private static object P1 { get; }
    private static object P2 { get; } = new object();
    private static object P3 { get; set; }
    private static object P4 { get; set; } = new object();
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (4,27): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     private static object F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(4, 27),
                // (6,36): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     private readonly static object F3;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F3").WithArguments("field", "F3").WithLocation(6, 36),
                // (8,27): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     private static object P1 { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P1").WithArguments("property", "P1").WithLocation(8, 27),
                // (10,27): warning CS8618: Non-nullable property 'P3' is uninitialized. Consider declaring the property as nullable.
                //     private static object P3 { get; set; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P3").WithArguments("property", "P3").WithLocation(10, 27));
        }

        [Fact]
        [WorkItem(34668, "https://github.com/dotnet/roslyn/issues/34668")]
        public void StaticFields_ExplicitConstructor()
        {
            var source =
@"class C
{
#pragma warning disable 0169
    private static object F1;
    private static object F2 = new object();
    private static object F3;
    private readonly static object F4;
    private readonly static object F5 = new object();
    private readonly static object F6;
    private static object P1 { get; }
    private static object P2 { get; } = new object();
    private static object P3 { get; }
    private static object P4 { get; set; }
    private static object P5 { get; set; } = new object();
    private static object P6 { get; set; }
    static C()
    {
        F3 = new object();
        F6 = new object();
        P3 = new object();
        P6 = new object();
    }
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (16,12): warning CS8618: Non-nullable field 'F4' is uninitialized. Consider declaring the field as nullable.
                //     static C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F4").WithLocation(16, 12),
                // (16,12): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     static C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P1").WithLocation(16, 12),
                // (16,12): warning CS8618: Non-nullable property 'P4' is uninitialized. Consider declaring the property as nullable.
                //     static C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P4").WithLocation(16, 12),
                // (16,12): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     static C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F1").WithLocation(16, 12));
        }

        [Fact]
        public void FieldInitializer_Simple_01()
        {
            var source = @"
class C
{
    string field = ""hello"";
    public C()
    {
        field.ToString();
    }
}
";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void FieldInitializer_Simple_02()
        {
            var source = @"
class C
{
    string Prop { get; set; } = ""hello"";
    public C()
    {
        Prop.ToString();
    }
}
";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void PropertyInitializer_AllowNullT_01()
        {
            var source = @"
using System.Diagnostics.CodeAnalysis;

class C<T>
{
    [AllowNull]
    T Prop { get; set; }
    public C()
    {
        Prop = default;
    }
}
";
            var comp = CreateCompilation(new[] { source, AllowNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void PropertyInitializer_AllowNullT_02()
        {
            var source = @"
using System.Diagnostics.CodeAnalysis;

class C<T>
{
    [AllowNull]
    T Prop { get; set; }
    public C()
    {
    }
}
";
            var comp = CreateCompilation(new[] { source, AllowNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void FieldInitializer_AllowNullT_01()
        {
            var source = @"
using System.Diagnostics.CodeAnalysis;

class C<T>
{
    [AllowNull]
    T field;
    public C()
    {
        field = default;
    }
}
";
            var comp = CreateCompilation(new[] { source, AllowNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (7,7): warning CS0414: The field 'C<T>.field' is assigned but its value is never used
                //     T field;
                Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "field").WithArguments("C<T>.field").WithLocation(7, 7)
                );
        }

        [Fact]
        public void FieldInitializer_AllowNullT_02()
        {
            var source = @"
using System.Diagnostics.CodeAnalysis;

class C<T>
{
    [AllowNull]
    T field;
    public C()
    {
    }
}
";
            var comp = CreateCompilation(new[] { source, AllowNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (7,7): warning CS0169: The field 'C<T>.field' is never used
                //     T field;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "field").WithArguments("C<T>.field").WithLocation(7, 7)
                );
        }

        [Fact]
        [WorkItem(34668, "https://github.com/dotnet/roslyn/issues/34668")]
        [WorkItem(37511, "https://github.com/dotnet/roslyn/issues/37511")]
        public void StaticFields_GenericTypes()
        {
            var source =
@"#pragma warning disable 0169
using System.Diagnostics.CodeAnalysis;
class C<T, U, V>
    where U : class
    where V : struct
{
    private static T P1 { get; }
    private static T P2 { get; } = default!;
    [MaybeNull] private static T P3 { get; }
    [MaybeNull] private static T P4 { get; } = default;
    private static U P5 { get; set; }
    private static U P6 { get; set; } = default!;
    private static U? P7 { get; }
    private static U? P8 { get; } = default;
    private static V P9 { get; set; }
    private static V P10 { get; set; } = default;
    private static V? P11 { get; }
    private static V? P12 { get; } = default;
}";
            var comp = CreateCompilation(new[] { MaybeNullAttributeDefinition, source }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (7,22): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     private static T P1 { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P1").WithArguments("property", "P1").WithLocation(7, 22),
                // (10,48): warning CS8601: Possible null reference assignment.
                //     [MaybeNull] private static T P4 { get; } = default;
                Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "default").WithLocation(10, 48),
                // (11,22): warning CS8618: Non-nullable property 'P5' is uninitialized. Consider declaring the property as nullable.
                //     private static U P5 { get; set; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P5").WithArguments("property", "P5").WithLocation(11, 22));
        }

        [Fact]
        [WorkItem(34668, "https://github.com/dotnet/roslyn/issues/34668")]
        public void StaticEvents()
        {
            var source =
@"#pragma warning disable 0067
#pragma warning disable 0414
delegate void D();
class C
{
    private static event D E1;
    private static event D E2 = null!;
    private static event D E3;
    private static event D E4;
    private static event D? E5;
    private static event D? E6 = null;
    static C()
    {
        D d = () => { };
        E1 = d;
        E3 += d;
    }
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (12,12): warning CS8618: Non-nullable event 'E4' is uninitialized. Consider declaring the event as nullable.
                //     static C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("event", "E4").WithLocation(12, 12));
        }

        [Fact]
        [WorkItem(34668, "https://github.com/dotnet/roslyn/issues/34668")]
        public void StaticFields_NotAllPaths()
        {
            var source =
@"#pragma warning disable 0169
class C
{
    private static bool F() => true;
    private static object F1;
    private static object F2;
    private static object F3;
    static C()
    {
        if (F()) F1 = new object();
        else F2 = new object();
        F3 = new object();
    }
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (8,12): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     static C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F1").WithLocation(8, 12),
                // (8,12): warning CS8618: Non-nullable field 'F2' is uninitialized. Consider declaring the field as nullable.
                //     static C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F2").WithLocation(8, 12));
        }

        [Fact]
        public void NestedType()
        {
            var source =
@"#pragma warning disable 0067
#pragma warning disable 0169
#pragma warning disable 0414
delegate void D();
struct S
{
    class C
    {
        static object F1;
        static object P1 { get; }
        static event D E1;
        object F2;
        object P2 { get; }
        event D E2;
    }
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (9,23): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //         static object F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(9, 23),
                // (10,23): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //         static object P1 { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P1").WithArguments("property", "P1").WithLocation(10, 23),
                // (11,24): warning CS8618: Non-nullable event 'E1' is uninitialized. Consider declaring the event as nullable.
                //         static event D E1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "E1").WithArguments("event", "E1").WithLocation(11, 24),
                // (12,16): warning CS8618: Non-nullable field 'F2' is uninitialized. Consider declaring the field as nullable.
                //         object F2;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F2").WithArguments("field", "F2").WithLocation(12, 16),
                // (13,16): warning CS8618: Non-nullable property 'P2' is uninitialized. Consider declaring the property as nullable.
                //         object P2 { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P2").WithArguments("property", "P2").WithLocation(13, 16),
                // (14,17): warning CS8618: Non-nullable event 'E2' is uninitialized. Consider declaring the event as nullable.
                //         event D E2;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "E2").WithArguments("event", "E2").WithLocation(14, 17));
        }

        // Each constructor is handled in isolation.
        [Fact]
        public void ChainedConstructors()
        {
            var source =
@"class C
{
    private object F1;
    private object F2;
    private readonly object F3;
    private object F4 = new object();
    private C()
    {
        F1 = new object();
    }
    internal C(object x) : this()
    {
        F2 = x;
    }
    internal C(object x, object y) : this(x)
    {
        F3 = y;
    }
    internal C(object x, object y, object z) : this()
    {
        F3 = z;
    }
    internal C(object x, object y, string z) : base()
    {
        F3 = z;
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (7,13): warning CS8618: Non-nullable field 'F2' is uninitialized. Consider declaring the field as nullable.
                //     private C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F2").WithLocation(7, 13),
                // (7,13): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     private C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F3").WithLocation(7, 13),
                // (23,14): warning CS8618: Non-nullable field 'F2' is uninitialized. Consider declaring the field as nullable.
                //     internal C(object x, object y, string z) : base()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F2").WithLocation(23, 14),
                // (23,14): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     internal C(object x, object y, string z) : base()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F1").WithLocation(23, 14));
        }

        [Fact]
        public void StructConstructorInitializer_UninitializedProperty()
        {
            var source = @"
struct S1
{
    public string Prop { get; set; }
    public S1(string s) // 1
    {
        Prop.ToString(); // 2
    }

    public S1(object obj) : this()
    {
        Prop.ToString(); // 3
    }

    public S1(object obj1, object obj2) : this() // 4
    {
    }

    public S1(string s1, string s2) : this(s1)
    {
        Prop.ToString();
    }
}
";

            var comp = CreateCompilation(source, options: WithNullableEnable(), parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (5,12): error CS0843: Auto-implemented property 'S1.Prop' must be fully assigned before control is returned to the caller. Consider updating to language version '11.0' to auto-default the property.
                //     public S1(string s) // 1
                Diagnostic(ErrorCode.ERR_UnassignedThisAutoPropertyUnsupportedVersion, "S1").WithArguments("S1.Prop", "11.0").WithLocation(5, 12),
                // (7,9): warning CS8602: Dereference of a possibly null reference.
                //         Prop.ToString(); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "Prop").WithLocation(7, 9),
                // (7,9): error CS9014: Use of possibly unassigned auto-implemented property 'Prop'. Consider updating to language version '11.0' to auto-default the property.
                //         Prop.ToString(); // 2
                Diagnostic(ErrorCode.ERR_UseDefViolationPropertyUnsupportedVersion, "Prop").WithArguments("Prop", "11.0").WithLocation(7, 9),
                // (12,9): warning CS8602: Dereference of a possibly null reference.
                //         Prop.ToString(); // 3
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "Prop").WithLocation(12, 9),
                // (15,12): warning CS8618: Non-nullable property 'Prop' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public S1(object obj1, object obj2) : this() // 4
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S1").WithArguments("property", "Prop").WithLocation(15, 12));

            var verifier = CompileAndVerify(source, options: WithNullableEnable(), parseOptions: TestOptions.Regular11);
            verifier.VerifyDiagnostics(
                // (7,9): warning CS8602: Dereference of a possibly null reference.
                //         Prop.ToString(); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "Prop").WithLocation(7, 9),
                // (12,9): warning CS8602: Dereference of a possibly null reference.
                //         Prop.ToString(); // 3
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "Prop").WithLocation(12, 9),
                // (15,12): warning CS8618: Non-nullable property 'Prop' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public S1(object obj1, object obj2) : this() // 4
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S1").WithArguments("property", "Prop").WithLocation(15, 12));

            verifier.VerifyIL("S1..ctor(string)", @"
{
  // Code size       20 (0x14)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldnull
  IL_0002:  stfld      ""string S1.<Prop>k__BackingField""
  IL_0007:  ldarg.0
  IL_0008:  call       ""readonly string S1.Prop.get""
  IL_000d:  callvirt   ""string object.ToString()""
  IL_0012:  pop
  IL_0013:  ret
}
");

            verifier.VerifyIL("S1..ctor(object, object)", @"
{
  // Code size        8 (0x8)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  initobj    ""S1""
  IL_0007:  ret
}
");

            verifier.VerifyIL("S1..ctor(string, string)", @"
{
  // Code size       20 (0x14)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  call       ""S1..ctor(string)""
  IL_0007:  ldarg.0
  IL_0008:  call       ""readonly string S1.Prop.get""
  IL_000d:  callvirt   ""string object.ToString()""
  IL_0012:  pop
  IL_0013:  ret
}
");
        }

        [Fact, WorkItem(48574, "https://github.com/dotnet/roslyn/issues/48574")]
        public void StructConstructorInitializer_UninitializedField()
        {
            var source = @"
#nullable enable

public struct S1
{
    public string field;

    public S1(object obj) : this()
    {
        field.ToString(); // 1
    }

    public S1(object obj1, object obj2) : this() // 2
    {
    }

    public S1(string s1, string s2) : this(s1)
    {
        field.ToString();
    }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (10,9): warning CS8602: Dereference of a possibly null reference.
                //         field.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "field").WithLocation(10, 9),
                // (13,12): warning CS8618: Non-nullable field 'field' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     public S1(object obj1, object obj2) : this() // 2
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S1").WithArguments("field", "field").WithLocation(13, 12));
        }

        [Fact, WorkItem(48574, "https://github.com/dotnet/roslyn/issues/48574")]
        public void StructConstructorInitializer_NestedUninitializedField()
        {
            var source = @"
#nullable enable
public struct S1
{
    public object F1;
    public S2 S2;

    public S1()
    {
        F1.ToString(); // 1
        S2.F2.ToString(); // missing warning: https://github.com/dotnet/roslyn/issues/60038
    }
}
public struct S2
{
    public object F2;
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
            comp.VerifyDiagnostics(
                // (10,9): warning CS8602: Dereference of a possibly null reference.
                //         F1.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "F1").WithLocation(10, 9));
        }

        [Fact, WorkItem(48574, "https://github.com/dotnet/roslyn/issues/48574")]
        public void StructConstructorInitializer_InitializedFieldViaParameterlessConstructor()
        {
            var source = @"
#nullable enable

new S1(new object());

struct S1
{
    public string field;

    public S1()
    {
        field = ""ok "";
    }

    public S1(object obj) : this()
    {
        System.Console.Write(field);
    }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
            var verifier = CompileAndVerify(comp, expectedOutput: "ok");

            verifier.VerifyIL("S1..ctor(object)", @"
{
  // Code size       18 (0x12)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       ""S1..ctor()""
  IL_0006:  ldarg.0
  IL_0007:  ldfld      ""string S1.field""
  IL_000c:  call       ""void System.Console.Write(string)""
  IL_0011:  ret
}
");
        }

        [Fact, WorkItem(48574, "https://github.com/dotnet/roslyn/issues/48574")]
        public void StructConstructorInitializer_UninitializedFieldWithParameterlessConstructor()
        {
            var source = @"
#nullable enable

struct S1
{
    public string field;

    public S1()
    {
        field = ""ok "";
    }

    public S1(string s) // 1, 2
    {
        System.Console.Write(field); // 3
    }
}
";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
            comp.VerifyDiagnostics(
                // (13,12): warning CS8618: Non-nullable field 'field' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     public S1(string s) // 1, 2
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S1").WithArguments("field", "field").WithLocation(13, 12),
                // (13,12): error CS0171: Field 'S1.field' must be fully assigned before control is returned to the caller. Consider updating to language version '11.0' to auto-default the field.
                //     public S1(string s) // 1, 2
                Diagnostic(ErrorCode.ERR_UnassignedThisUnsupportedVersion, "S1").WithArguments("S1.field", "11.0").WithLocation(13, 12),
                // (15,30): error CS9015: Use of possibly unassigned field 'field'. Consider updating to language version '11.0' to auto-default the field.
                //         System.Console.Write(field); // 3
                Diagnostic(ErrorCode.ERR_UseDefViolationFieldUnsupportedVersion, "field").WithArguments("field", "11.0").WithLocation(15, 30)
                );

            var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular11);
            verifier.VerifyDiagnostics(
                // (13,12): warning CS8618: Non-nullable field 'field' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     public S1(string s) // 1, 2
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S1").WithArguments("field", "field").WithLocation(13, 12)
                );

            verifier.VerifyIL("S1..ctor()", @"
{
  // Code size       12 (0xc)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldstr      ""ok ""
  IL_0006:  stfld      ""string S1.field""
  IL_000b:  ret
}
");

            verifier.VerifyIL("S1..ctor(string)", @"
{
  // Code size       19 (0x13)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldnull
  IL_0002:  stfld      ""string S1.field""
  IL_0007:  ldarg.0
  IL_0008:  ldfld      ""string S1.field""
  IL_000d:  call       ""void System.Console.Write(string)""
  IL_0012:  ret
}
");
        }

        [Fact, WorkItem(48574, "https://github.com/dotnet/roslyn/issues/48574")]
        public void StructConstructorInitializer_InitializedFieldViaInitializer()
        {
            var source = @"
#nullable enable

new S1();
new S1(new object());
new S1(new object(), new object());

struct S1
{
    public string field = ""ok "";

    public S1()
    {
        System.Console.Write(field);
    }

    public S1(object s)
    {
        System.Console.Write(field);
    }

    public S1(object obj, object obj2) : this()
    {
        System.Console.Write(field);
    }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();

            var verifier = CompileAndVerify(comp, expectedOutput: "ok ok ok ok");

            verifier.VerifyIL("S1..ctor()", @"
{
  // Code size       23 (0x17)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldstr      ""ok ""
  IL_0006:  stfld      ""string S1.field""
  IL_000b:  ldarg.0
  IL_000c:  ldfld      ""string S1.field""
  IL_0011:  call       ""void System.Console.Write(string)""
  IL_0016:  ret
}
");

            verifier.VerifyIL("S1..ctor(object)", @"
{
  // Code size       23 (0x17)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldstr      ""ok ""
  IL_0006:  stfld      ""string S1.field""
  IL_000b:  ldarg.0
  IL_000c:  ldfld      ""string S1.field""
  IL_0011:  call       ""void System.Console.Write(string)""
  IL_0016:  ret
}
");

            verifier.VerifyIL("S1..ctor(object, object)", @"
{
  // Code size       18 (0x12)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       ""S1..ctor()""
  IL_0006:  ldarg.0
  IL_0007:  ldfld      ""string S1.field""
  IL_000c:  call       ""void System.Console.Write(string)""
  IL_0011:  ret
}
");
        }

        [Fact, WorkItem(43215, "https://github.com/dotnet/roslyn/issues/43215")]
        public void FieldInitializer_CallWithOutParam()
        {
            var source = @"
class C
{
    static string field1;
    static string field2 = M(out field1);

    public static string M(out string param1)
    {
        param1 = ""hello"";
        return ""world"";
    }
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void ReadWriteAutoProperties_ExplicitConstructors()
        {
            var source =
@"class C
{
    private object P1 { get; set; }
    internal object? P2 { get; set; }
    internal object?[] P3 { get; set; }
    private object[]? P4 { get; set; }
    internal C()
    {
    }
    internal C(object o)
    {
        P1 = o;
        P3 = new[] { o,  null };
    }
    internal C(object x, object y)
    {
        P2 = x;
        P4 = new[] { x, y };
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (7,14): warning CS8618: Non-nullable property 'P3' is uninitialized. Consider declaring the property as nullable.
                //     internal C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P3").WithLocation(7, 14),
                // (7,14): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     internal C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P1").WithLocation(7, 14),
                // (15,14): warning CS8618: Non-nullable property 'P3' is uninitialized. Consider declaring the property as nullable.
                //     internal C(object x, object y)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P3").WithLocation(15, 14),
                // (15,14): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     internal C(object x, object y)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P1").WithLocation(15, 14));
        }

        [Fact]
        public void ReadOnlyAutoProperties_ExplicitConstructors()
        {
            var source =
@"class C
{
    private object P1 { get; }
    internal object? P2 { get; }
    internal object?[] P3 { get; }
    private object[]? P4 { get; }
    internal C()
    {
    }
    internal C(object o)
    {
        P1 = o;
        P3 = new[] { o,  null };
    }
    internal C(object x, object y)
    {
        P2 = x;
        P4 = new[] { x, y };
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (7,14): warning CS8618: Non-nullable property 'P3' is uninitialized. Consider declaring the property as nullable.
                //     internal C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P3").WithLocation(7, 14),
                // (7,14): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     internal C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P1").WithLocation(7, 14),
                // (15,14): warning CS8618: Non-nullable property 'P3' is uninitialized. Consider declaring the property as nullable.
                //     internal C(object x, object y)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P3").WithLocation(15, 14),
                // (15,14): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     internal C(object x, object y)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P1").WithLocation(15, 14));
        }

        [Fact]
        public void AutoPropertyInitializers_DefaultConstructor()
        {
            var source =
@"class C
{
    private object P1 { get; } = new object();
    internal object P2 { get; set; } = new object();
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void AutoPropertyInitializers_ExplicitConstructors()
        {
            var source =
@"class C
{
    private object P1 { get; } = new object();
    internal object?[] P2 { get; } = new object?[0];
    internal object P3 { get; set; } = new object();
    private object?[] P4 { get; set; } = new object?[0];
    internal C(object o)
    {
        P1 = o;
        P2 = new object?[] { o };
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void Properties_ExplicitImplementations()
        {
            var source =
@"using System;
class C
{
    private object P1 { get { throw new NotImplementedException(); } }
    private object[] P2 { get { throw new NotImplementedException(); } set { } }
    private object P3 { set { } }
    private static object P4 { get { throw new NotImplementedException(); } }
    private static object P5 { set { } }
    internal C()
    {
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [Fact]
        [WorkItem(37511, "https://github.com/dotnet/roslyn/issues/37511")]
        public void GenericType()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
class C<T>
{
#pragma warning disable 0169
    private readonly T F1;
    private readonly T F2;
    [MaybeNull] private readonly T F3;
    private T P1 { get; }
    private T P2 { get; set; }
    internal T P3 { get; }
    internal T P4 { get; set; }
    private C(T t)
    {
        F1 = t;
        P1 = t;
        P4 = t;
    }
}";
            var comp = CreateCompilation(new[] { MaybeNullAttributeDefinition, source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (12,13): warning CS8618: Non-nullable field 'F2' is uninitialized. Consider declaring the field as nullable.
                //     private C(T t)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F2").WithLocation(12, 13),
                // (12,13): warning CS8618: Non-nullable property 'P2' is uninitialized. Consider declaring the property as nullable.
                //     private C(T t)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P2").WithLocation(12, 13),
                // (12,13): warning CS8618: Non-nullable property 'P3' is uninitialized. Consider declaring the property as nullable.
                //     private C(T t)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P3").WithLocation(12, 13));
        }

        [Fact]
        public void GenericType_ClassConstraint()
        {
            var source =
@"class C<T> where T : class
{
#pragma warning disable 0169
    private readonly T F1;
    private readonly T? F2;
    private T P1 { get; }
    private T? P2 { get; set; }
    internal T? P3 { get; }
    internal T P4{ get; set; }
    private C()
    {
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (10,13): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     private C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P1").WithLocation(10, 13),
                // (10,13): warning CS8618: Non-nullable property 'P4' is uninitialized. Consider declaring the property as nullable.
                //     private C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P4").WithLocation(10, 13),
                // (10,13): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     private C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F1").WithLocation(10, 13));
        }

        [Fact]
        public void GenericType_StructConstraint()
        {
            var source =
@"class C<T> where T : struct
{
#pragma warning disable 0169
    private readonly T F1;
    private readonly T? F2;
    private C()
    {
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [WorkItem(29065, "https://github.com/dotnet/roslyn/issues/29065")]
        [WorkItem(30021, "https://github.com/dotnet/roslyn/issues/30021")]
        [Fact]
        public void GenericType_NonNullTypes()
        {
            var source =
@"#pragma warning disable 0169
class A<T>
{
    T F1; // warning: uninitialized
    A() { }
}
class B<T> where T : class
{
    T F2; // warning: uninitialized
    T? F3;
    B() { }
}
class C<T> where T : struct
{
    T F4;
    T? F5;
    C() { }
}";

            // [NonNullTypes(true)]
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (11,5): warning CS8618: Non-nullable field 'F2' is uninitialized. Consider declaring the field as nullable.
                //     B() { }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "B").WithArguments("field", "F2").WithLocation(11, 5),
                // (5,5): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     A() { }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "A").WithArguments("field", "F1").WithLocation(5, 5));

            // [NonNullTypes(false)]
            comp = CreateCompilation(new[] { source }, options: WithNullableDisable(), parseOptions: TestOptions.Regular8);

            comp.VerifyDiagnostics(
                // (10,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     T? F3;
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 6),
                // (10,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type unless language version '9.0' or greater is used. Consider changing the language version or adding a 'class', 'struct', or type constraint.
                //     T? F3;
                Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithArguments("9.0").WithLocation(10, 5));

            // [NonNullTypes] missing
            comp = CreateCompilation(source, parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (10,6): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     T? F3;
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(10, 6),
                // (10,5): error CS8627: A nullable type parameter must be known to be a value type or non-nullable reference type unless language version '9.0' or greater is used. Consider changing the language version or adding a 'class', 'struct', or type constraint.
                //     T? F3;
                Diagnostic(ErrorCode.ERR_NullableUnconstrainedTypeParameter, "T?").WithArguments("9.0").WithLocation(10, 5));

            // https://github.com/dotnet/roslyn/issues/29976: Test with [NonNullTypes(Warnings=false)].
        }

        [Fact]
        public void GenericType_NoConstraint()
        {
            var source =
@"#nullable enable
#pragma warning disable 0169
class C<T>
{
    private T F1;
    private T? F2;
    private T P1 { get; }
    private T? P2 { get; }
#nullable disable
    private T F3;
    private T? F4;
    private T P3 { get; }
    private T? P4 { get; }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (5,15): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     private T F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(5, 15),
                // (7,15): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     private T P1 { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P1").WithArguments("property", "P1").WithLocation(7, 15),
                // (11,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? F4;
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 14),
                // (13,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? P4 { get; }
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 14));
        }

        [Fact]
        public void GenericType_NullableClassConstraint()
        {
            var source =
@"#nullable enable
#pragma warning disable 0169
class C<T> where T : class?
{
    private T F1;
    private T? F2;
    private T P1 { get; }
    private T? P2 { get; }
#nullable disable
    private T F3;
    private T? F4;
    private T P3 { get; }
    private T? P4 { get; }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (5,15): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     private T F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(5, 15),
                // (7,15): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     private T P1 { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P1").WithArguments("property", "P1").WithLocation(7, 15),
                // (11,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? F4;
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 14),
                // (13,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? P4 { get; }
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 14));
        }

        [Fact]
        public void GenericType_NotNullConstraint()
        {
            var source =
@"#nullable enable
#pragma warning disable 0169
class C<T> where T : notnull
{
    private T F1;
    private T? F2;
    private T P1 { get; }
    private T? P2 { get; }
#nullable disable
    private T F3;
    private T? F4;
    private T P3 { get; }
    private T? P4 { get; }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (5,15): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     private T F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(5, 15),
                // (7,15): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     private T P1 { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P1").WithArguments("property", "P1").WithLocation(7, 15),
                // (11,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? F4;
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(11, 14),
                // (13,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? P4 { get; }
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(13, 14));
        }

        [Fact]
        public void GenericType_UnmanagedConstraint()
        {
            var source =
@"#nullable enable
#pragma warning disable 0169
class C<T> where T : unmanaged
{
    private T F1;
    private T? F2;
    private T P1 { get; }
    private T? P2 { get; }
#nullable disable
    private T F3;
    private T? F4;
    private T P3 { get; }
    private T? P4 { get; }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void GenericType_InterfaceConstraint_01()
        {
            var source =
@"#nullable enable
#pragma warning disable 0169
interface I { }
class C<T> where T : I
{
    private T F1;
    private T? F2;
    private T P1 { get; }
    private T? P2 { get; }
#nullable disable
    private T F3;
    private T? F4;
    private T P3 { get; }
    private T? P4 { get; }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (6,15): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     private T F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(6, 15),
                // (8,15): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     private T P1 { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P1").WithArguments("property", "P1").WithLocation(8, 15),
                // (12,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? F4;
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(12, 14),
                // (14,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? P4 { get; }
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(14, 14));
        }

        [Fact]
        public void GenericType_InterfaceConstraint_02()
        {
            var source =
@"#nullable enable
#pragma warning disable 0169
interface I { }
class C<T> where T : I?
{
    private T F1;
    private T? F2;
    private T P1 { get; }
    private T? P2 { get; }
#nullable disable
    private T F3;
    private T? F4;
    private T P3 { get; }
    private T? P4 { get; }
}";
            var comp = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            comp.VerifyDiagnostics(
                // (6,15): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     private T F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(6, 15),
                // (8,15): warning CS8618: Non-nullable property 'P1' is uninitialized. Consider declaring the property as nullable.
                //     private T P1 { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "P1").WithArguments("property", "P1").WithLocation(8, 15),
                // (12,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? F4;
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(12, 14),
                // (14,14): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
                //     private T? P4 { get; }
                Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(14, 14));
        }

        [Fact]
        public void TypeParameterConstraints()
        {
            var source =
@"#pragma warning disable 0169
interface I { }
class A { }
class C1<T, U> where U : T
{
    T F1;
    U G1;
}
class C2<T> where T : struct
{
    T F2;
}
class C3<T, U> where T : class where U : T
{
    T F3;
    U G3;
}
class C4<T, U> where T : I where U : T
{
    T F4;
    U G4;
}
class C5<T, U> where T : A where U : T
{
    T F5;
    U G5;
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (6,7): warning CS8618: Non-nullable field 'F1' is uninitialized. Consider declaring the field as nullable.
                //     T F1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F1").WithArguments("field", "F1").WithLocation(6, 7),
                // (7,7): warning CS8618: Non-nullable field 'G1' is uninitialized. Consider declaring the field as nullable.
                //     U G1;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "G1").WithArguments("field", "G1").WithLocation(7, 7),
                // (15,7): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     T F3;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F3").WithArguments("field", "F3").WithLocation(15, 7),
                // (16,7): warning CS8618: Non-nullable field 'G3' is uninitialized. Consider declaring the field as nullable.
                //     U G3;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "G3").WithArguments("field", "G3").WithLocation(16, 7),
                // (20,7): warning CS8618: Non-nullable field 'F4' is uninitialized. Consider declaring the field as nullable.
                //     T F4;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F4").WithArguments("field", "F4").WithLocation(20, 7),
                // (21,7): warning CS8618: Non-nullable field 'G4' is uninitialized. Consider declaring the field as nullable.
                //     U G4;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "G4").WithArguments("field", "G4").WithLocation(21, 7),
                // (25,7): warning CS8618: Non-nullable field 'F5' is uninitialized. Consider declaring the field as nullable.
                //     T F5;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F5").WithArguments("field", "F5").WithLocation(25, 7),
                // (26,7): warning CS8618: Non-nullable field 'G5' is uninitialized. Consider declaring the field as nullable.
                //     U G5;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "G5").WithArguments("field", "G5").WithLocation(26, 7));
        }

        [Fact]
        public void Tuple()
        {
            var source =
@"class C
{
#pragma warning disable 0649
    internal readonly (object A, object B) F1;
    internal readonly (object? A, object) F2;
    internal readonly (object, object? B) F3;
    internal readonly (object?, object?) F4;
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void NotInitializedInAllPaths_Class()
        {
            var source =
@"class C
{
#pragma warning disable 0169
    private readonly string F;
    private string[] P { get; }
    internal C(string s)
    {
        if (s.Length > 0)
            F = s;
        else
            P = new [] { s };
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (6,14): warning CS8618: Non-nullable property 'P' is uninitialized. Consider declaring the property as nullable.
                //     internal C(string s)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "P").WithLocation(6, 14),
                // (6,14): warning CS8618: Non-nullable field 'F' is uninitialized. Consider declaring the field as nullable.
                //     internal C(string s)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F").WithLocation(6, 14));
        }

        [Fact]
        public void NotInitializedInAllPaths_Struct()
        {
            var source =
@"struct S
{
#pragma warning disable 0169
    private readonly string F;
    private string[] P { get; set; }
    internal S(string s)
    {
        if (s.Length > 0)
            F = s;
        else
            P = new [] { s };
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (6,14): warning CS8618: Non-nullable property 'P' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     internal S(string s)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S").WithArguments("property", "P").WithLocation(6, 14),
                // (6,14): warning CS8618: Non-nullable field 'F' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     internal S(string s)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S").WithArguments("field", "F").WithLocation(6, 14),
                // (6,14): error CS0843: Auto-implemented property 'S.P' must be fully assigned before control is returned to the caller. Consider updating to language version '11.0' to auto-default the property.
                //     internal S(string s)
                Diagnostic(ErrorCode.ERR_UnassignedThisAutoPropertyUnsupportedVersion, "S").WithArguments("S.P", "11.0").WithLocation(6, 14),
                // (6,14): error CS0171: Field 'S.F' must be fully assigned before control is returned to the caller. Consider updating to language version '11.0' to auto-default the field.
                //     internal S(string s)
                Diagnostic(ErrorCode.ERR_UnassignedThisUnsupportedVersion, "S").WithArguments("S.F", "11.0").WithLocation(6, 14));

            var verifier = CompileAndVerify(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular11);
            verifier.VerifyDiagnostics(
                // (6,14): warning CS8618: Non-nullable property 'P' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     internal S(string s)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S").WithArguments("property", "P").WithLocation(6, 14),
                // (6,14): warning CS8618: Non-nullable field 'F' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     internal S(string s)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S").WithArguments("field", "F").WithLocation(6, 14));
            verifier.VerifyIL("S..ctor", @"
{
  // Code size       48 (0x30)
  .maxstack  5
  IL_0000:  ldarg.0
  IL_0001:  ldnull
  IL_0002:  stfld      ""string S.F""
  IL_0007:  ldarg.0
  IL_0008:  ldnull
  IL_0009:  stfld      ""string[] S.<P>k__BackingField""
  IL_000e:  ldarg.1
  IL_000f:  callvirt   ""int string.Length.get""
  IL_0014:  ldc.i4.0
  IL_0015:  ble.s      IL_001f
  IL_0017:  ldarg.0
  IL_0018:  ldarg.1
  IL_0019:  stfld      ""string S.F""
  IL_001e:  ret
  IL_001f:  ldarg.0
  IL_0020:  ldc.i4.1
  IL_0021:  newarr     ""string""
  IL_0026:  dup
  IL_0027:  ldc.i4.0
  IL_0028:  ldarg.1
  IL_0029:  stelem.ref
  IL_002a:  call       ""void S.P.set""
  IL_002f:  ret
}
");
        }

        [Fact]
        public void EmptyStruct()
        {
            var source =
@"struct S
{
    S(object o)
    {
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [Fact]
        [WorkItem(30022, "https://github.com/dotnet/roslyn/issues/30022")]
        public void StructAssignThis()
        {
            var source =
@"struct S
{
#pragma warning disable 0169
    private readonly string F;
    private string[] P { get; set; }
    internal S(S s)
    {
        this = s;
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void StructObjectCreation()
        {
            var source =
@"#pragma warning disable 0649
struct S
{
    internal string F;
    internal string G;
}
class C
{
    static void F(S s) { }
    static void Main()
    {
        F(new S());
        F(new S() { F = string.Empty });
    }
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void ValueTypeFields()
        {
            var source =
@"#pragma warning disable 0169
struct S { }
class C
{
    private readonly S s;
    private int i;
}";
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void ValueType_NoConstructors()
        {
            var source =
@"#nullable enable
#pragma warning disable 0169
struct S
{
    object F1;
    static object F2;
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,19): warning CS8618: Non-nullable field 'F2' is uninitialized. Consider declaring the field as nullable.
                //     static object F2;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F2").WithArguments("field", "F2").WithLocation(6, 19));
        }

        [Fact]
        public void ValueType_InstanceConstructor()
        {
            var source =
@"#nullable enable
#pragma warning disable 0169
struct S
{
    object F1;
    static object F2;
    S(int i)
    {
        F1 = new object();
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (6,19): warning CS8618: Non-nullable field 'F2' is uninitialized. Consider declaring the field as nullable.
                //     static object F2;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F2").WithArguments("field", "F2").WithLocation(6, 19));
        }

        [Fact]
        public void ValueType_StaticConstructor()
        {
            var source =
@"#nullable enable
#pragma warning disable 0169
struct S
{
    object F1;
    static object F2;
    static object F3;
    static S()
    {
        F2 = new object();
    }
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics(
                // (8,12): warning CS8618: Non-nullable field 'F3' is uninitialized. Consider declaring the field as nullable.
                //     static S()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S").WithArguments("field", "F3").WithLocation(8, 12));
        }

        [Fact]
        public void Interface_01()
        {
            var source =
@"#nullable enable
public interface I
{
    public object F1; // 1
    public static object F2; // 2
    public static object F3 { get; set; } // 3
    public static event System.Action E1; // 4, 5
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (4,19): error CS0525: Interfaces cannot contain instance fields
                //     public object F1; // 1
                Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F1").WithLocation(4, 19),
                // (5,26): warning CS8618: Non-nullable field 'F2' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     public static object F2; // 2
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F2").WithArguments("field", "F2").WithLocation(5, 26),
                // (6,26): warning CS8618: Non-nullable property 'F3' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public static object F3 { get; set; } // 3
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "F3").WithArguments("property", "F3").WithLocation(6, 26),
                // (7,39): warning CS8618: Non-nullable event 'E1' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the event as nullable.
                //     public static event System.Action E1; // 4, 5
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "E1").WithArguments("event", "E1").WithLocation(7, 39),
                // (7,39): warning CS0067: The event 'I.E1' is never used
                //     public static event System.Action E1; // 4, 5
                Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("I.E1").WithLocation(7, 39)
                );
        }

        [Fact]
        public void Interface_02()
        {
            var source =
@"#nullable enable
public interface I
{
    public static object F1;
    public static object F2 { get; set; }
    public static event System.Action E1; // 1

    public static object F3 = new object();
    public static object F4 { get; set; } = new object();
    public static event System.Action E2 = () => {};

    public static object F5;
    public static object F6 { get; set; }
    public static event System.Action E3;

    static I() // 2, 3, 4
    {
        F5 = new object();
        F6 = new object();
        E3 = () => {};
    }
}";
            var comp = CreateCompilation(source, targetFramework: TargetFramework.NetCoreApp);
            comp.VerifyDiagnostics(
                // (6,39): warning CS0067: The event 'I.E1' is never used
                //     public static event System.Action E1; // 1
                Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("I.E1").WithLocation(6, 39),
                // (16,12): warning CS8618: Non-nullable property 'F2' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     static I() // 2, 3, 4
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "I").WithArguments("property", "F2").WithLocation(16, 12),
                // (16,12): warning CS8618: Non-nullable event 'E1' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the event as nullable.
                //     static I() // 2, 3, 4
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "I").WithArguments("event", "E1").WithLocation(16, 12),
                // (16,12): warning CS8618: Non-nullable field 'F1' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     static I() // 2, 3, 4
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "I").WithArguments("field", "F1").WithLocation(16, 12)
                );
        }

        [Fact]
        public void Enum()
        {
            var source =
@"#nullable enable
enum E
{
    A,
    B = A,
}";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void LocalFunction()
        {
            var source =
@"#pragma warning disable 0169
class C
{
    private object F;
    private object G;
    C()
    {
        void L(object o)
        {
            F = o;
        }
        L(new object());
    }
}";
            // Null state does not flow out of local functions https://github.com/dotnet/roslyn/issues/45770
            var comp = CreateCompilation(new[] { source }, options: WithNullableEnable(), parseOptions: TestOptions.Regular8);
            comp.VerifyDiagnostics(
                // (6,5): warning CS8618: Non-nullable field 'G' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "G").WithLocation(6, 5),
                // (6,5): warning CS8618: Non-nullable field 'F' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     C()
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "F").WithLocation(6, 5));
        }

        [Fact]
        [WorkItem(25529, "https://github.com/dotnet/roslyn/issues/25529")]
        public void UnassignedNonNullFieldsUnreachable()
        {
            var comp = CreateCompilation(@"
using System;
class C
{
    private object _f;
    internal C()
    {
        throw new NotImplementedException();
    }

    internal C(object o) { }

    internal C(string s)
    {
        return;
        throw new NotImplementedException();
    }

    internal C(int x)
    {
        if (x == 0)
        {
            return;
        }
        throw new NotImplementedException();
    }

    internal C(char c)
    {
        return;
    }
}
", options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (5,20): warning CS0169: The field 'C._f' is never used
                //     private object _f;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "_f").WithArguments("C._f").WithLocation(5, 20),
                // (11,14): warning CS8618: Non-nullable field '_f' is uninitialized. Consider declaring the field as nullable.
                //     internal C(object o) { }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "_f").WithLocation(11, 14),
                // (13,14): warning CS8618: Non-nullable field '_f' is uninitialized. Consider declaring the field as nullable.
                //     internal C(string s)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "_f").WithLocation(13, 14),
                // (19,14): warning CS8618: Non-nullable field '_f' is uninitialized. Consider declaring the field as nullable.
                //     internal C(int x)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "_f").WithLocation(19, 14),
                // (28,14): warning CS8618: Non-nullable field '_f' is uninitialized. Consider declaring the field as nullable.
                //     internal C(char c)
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("field", "_f").WithLocation(28, 14));
        }

        [Fact]
        [WorkItem(43523, "https://github.com/dotnet/roslyn/issues/43523")]
        [WorkItem(44046, "https://github.com/dotnet/roslyn/issues/44046")]
        public void IndirectInitialization_WithAssertsOrThrows()
        {
            var source = @"
using System;
using System.Diagnostics.CodeAnalysis;

class C1
{
    public string Prop { get; set; }
    void Init() => Prop = ""hello"";
    public C1() // 1
    {
        Init();
    }
}

class C2
{
    public string Prop { get; set; }
    void Init() => Prop = ""hello"";

    static void MyAssert([DoesNotReturnIf(false)] bool b) { if (!b) throw null!; }

    public C2()
    {
        Init();
        MyAssert(Prop is object);
    }
}

class C3
{
    public string Prop { get; set; }
    void Init() => Prop = ""hello"";
    public C3()
    {
        Init();
        if (Prop is null)
        {
            throw new Exception();
        }
    }
}";
            var comp = CreateCompilation(new[] { source, DoesNotReturnIfAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (9,12): warning CS8618: Non-nullable property 'Prop' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public C1() // 1
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C1").WithArguments("property", "Prop").WithLocation(9, 12));
        }

        [Fact]
        [WorkItem(41110, "https://github.com/dotnet/roslyn/issues/41110")]
        public void TrackMemberStateAcrossInitializers()
        {
            var source = @"
class C
{
  static string? P1 { get; set; } = """";

  static string P2 { get; set; } = P1;
  static string f1 = P1;
}

class D
{
  static string? f1 = """";

  static string f2 = f1;
  static string P1 { get; set; } = f1;
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics();
        }

        [Fact]
        [WorkItem(44180, "https://github.com/dotnet/roslyn/issues/44180")]
        public void MemberNotNull_PropertiesFields()
        {
            var source = @"
using System.Diagnostics.CodeAnalysis;

class Property
{
  public string P { get; set; }

  public Property() { Init(); P.ToString(); }

  [MemberNotNull(nameof(P))]  void Init() => P = """";
}

class Field
{
  public string F;

  public Field() { Init(); F.ToString(); }

  [MemberNotNull(nameof(F))] void Init() => F = """";
}";
            var comp = CreateCompilation(new[] { source, MemberNotNullAttributeDefinition }, options: WithNullableEnable(), parseOptions: TestOptions.RegularPreview);
            comp.VerifyDiagnostics();
        }

        [Fact]
        [WorkItem(41296, "https://github.com/dotnet/roslyn/issues/41296")]
        public void InitializeInTryAndInCatch()
        {
            var source = @"
using System;
public class C
{
    string field;

    public C()
    {
        try
        {
            M2(out field);
        }
        catch (Exception)
        {
           if (field is null)
           {
              field  =  """";
           }
        }
    }

    static void M2(out string s) => throw null!;
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics();
        }

        [Fact]
        [WorkItem(44212, "https://github.com/dotnet/roslyn/issues/44212")]
        public void InitializeUsingNullCoalescingAssignment()
        {
            var source = @"
using System.Diagnostics.CodeAnalysis;

class C
{
    string f;

    public C()
    {
        Prop ??= """";
        f.ToString();
    }

    public C(byte b)
    {
        if (Prop == null)
        {
            Prop = """";
        }
        f.ToString();
    }

    [MemberNotNull(nameof(f))]
    string? Prop
    {
        get => f = """";
        set => f = value ?? """";
    }
}
";
            var comp = CreateCompilation(new[] { source, MemberNotNullAttributeDefinition }, options: WithNullableEnable(), parseOptions: TestOptions.RegularPreview);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void BaseMembersHaveDeclaredStateInDerivedCtor()
        {
            var source = @"
class Base
{
    public string BaseProp { get; set; } // 1
}

class Derived : Base
{
    string DerivedProp { get; set; }

    public Derived()
    {
        BaseProp.ToString();
        DerivedProp.ToString(); // 2
    }
}
";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (4,19): warning CS8618: Non-nullable property 'BaseProp' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public string BaseProp { get; set; } // 1
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "BaseProp").WithArguments("property", "BaseProp").WithLocation(4, 19),
                // (14,9): warning CS8602: Dereference of a possibly null reference.
                //         DerivedProp.ToString(); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "DerivedProp").WithLocation(14, 9));
        }

        [Fact]
        public void NullableEnableWarnings_InitialState()
        {
            var source = @"
#nullable enable warnings
class C
{
    public string Prop { get; set; }
    public C()
    {
        Prop.ToString();
    }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void NullableEnableWarnings_NoExitWarning()
        {
            var source = @"
#nullable enable warnings
class C
{
    public string Prop { get; set; }
    public C()
    {
        Prop = null;
    }
}
";
            var comp = CreateCompilation(source);
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void NotNullIfNotNull_StaticInitializers_01()
        {
            var source = @"
using System.Diagnostics.CodeAnalysis;

public class C
{
    static string Field1 = M(Field2); // 1
    static string Field2 = M(Field1); // 2

    [return: NotNullIfNotNull(""input"")]
    public static string? M(string? input) => input;
}
";
            var comp = CreateCompilation(new[] { source, NotNullIfNotNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (6,28): warning CS8601: Possible null reference assignment.
                //     static string Field1 = M(Field2); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "M(Field2)").WithLocation(6, 28),
                // (7,28): warning CS8601: Possible null reference assignment.
                //     static string Field2 = M(Field1); // 2
                Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "M(Field1)").WithLocation(7, 28)
                );
        }

        [Fact]
        public void NotNullIfNotNull_StaticInitializers_02()
        {
            var source = @"
using System.Diagnostics.CodeAnalysis;

public class C
{
    static string? Field1 = ""a"";
    static string Field2 = M(Field1);

    [return: NotNullIfNotNull(""input"")]
    public static string? M(string? input) => input;
}
";
            var comp = CreateCompilation(new[] { source, NotNullIfNotNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics();
        }

        [Fact]
        public void NotNullIfNotNull_StaticInitializers_03()
        {
            var source = @"
public class C
{
    static string Field1 = Field2.ToString(); // 1
    static string Field2 = ""a"";
}
";
            var comp = CreateCompilation(new[] { source, NotNullIfNotNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (4,28): warning CS8602: Dereference of a possibly null reference.
                //     static string Field1 = Field2.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "Field2").WithLocation(4, 28));
        }

        [Fact]
        [WorkItem(46121, "https://github.com/dotnet/roslyn/issues/46121")]
        public void StaticInitializers_MultipleFiles_01()
        {
            var source1 = @"
partial class C
{
    static readonly string s1;
}";
            var source2 = @"
partial class C
{
    static C()
    {
        s1 = ""hello"";
    }
}
";
            var comp = CreateCompilation(new[] { source1, source2 }, options: WithNullableEnable());

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[0], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify();

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[1], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify();

            comp.VerifyDiagnostics(
                // (4,28): warning CS0414: The field 'C.s1' is assigned but its value is never used
                //     static readonly string s1;
                Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "s1").WithArguments("C.s1").WithLocation(4, 28)
                );
        }

        [Fact]
        [WorkItem(46121, "https://github.com/dotnet/roslyn/issues/46121")]
        public void StaticInitializers_MultipleFiles_02()
        {
            var source1 = @"
partial class C
{
    static readonly string Field1 = Field2.ToString(); // 1
}";
            var source2 = @"
partial class C
{
    static readonly string Field2 = ""a"";
}
";
            var comp = CreateCompilation(new[] { source1, source2 }, options: WithNullableEnable());

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[0], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify(
                    // (4,37): warning CS8602: Dereference of a possibly null reference.
                    //     static readonly string Field1 = Field2.ToString(); // 1
                    Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "Field2").WithLocation(4, 37));

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[1], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify();

            comp.VerifyDiagnostics(
                // (4,37): warning CS8602: Dereference of a possibly null reference.
                //     static readonly string Field1 = Field2.ToString(); // 1
                Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "Field2").WithLocation(4, 37));
        }

        [Fact]
        public void StaticInitializers_MultipleFiles_03()
        {
            var source1 = @"
public partial class Class1
{
    public static readonly string Value1;

    static Class1 ()
    {
        Value1 = string.Empty;
        Value2 = string.Empty;
    }
}
";
            var source2 = @"
public partial class Class1
{
    public static readonly string Value2;
}
";
            var comp = CreateCompilation(new[] { source1, source2 }, options: WithNullableEnable());

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[0], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify();

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[1], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify();

            comp.VerifyDiagnostics();
        }

        [Fact]
        public void StaticInitializers_MultipleFiles_04()
        {
            var source1 = @"
public partial class Class1
{
    public static readonly string Value1; // 1
}
";
            var source2 = @"
public partial class Class1
{
    public static readonly string Value2; // 2
}
";
            var comp = CreateCompilation(new[] { source1, source2 }, options: WithNullableEnable());

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[0], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify(
                    // (4,35): warning CS8618: Non-nullable field 'Value1' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                    //     public static readonly string Value1; // 1
                    Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Value1").WithArguments("field", "Value1").WithLocation(4, 35));

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[1], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify(
                    // (4,35): warning CS8618: Non-nullable field 'Value2' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                    //     public static readonly string Value2; // 2
                    Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Value2").WithArguments("field", "Value2").WithLocation(4, 35));

            comp.VerifyDiagnostics(
                // (4,35): warning CS8618: Non-nullable field 'Value1' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     public static readonly string Value1; // 1
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Value1").WithArguments("field", "Value1").WithLocation(4, 35),
                // (4,35): warning CS8618: Non-nullable field 'Value2' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     public static readonly string Value2; // 2
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Value2").WithArguments("field", "Value2").WithLocation(4, 35));
        }

        [Fact]
        public void StaticInitializers_MultipleFiles_05()
        {
            var source1 = @"
public partial class Class1
{
    public static readonly string Value1 = ""a"";
}
";
            var source2 = @"
public partial class Class1
{
    public static readonly string Value2; // 1
}
";
            var comp = CreateCompilation(new[] { source1, source2 }, options: WithNullableEnable());

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[0], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify();

            comp.GetDiagnosticsForSyntaxTree(CompilationStage.Compile, comp.SyntaxTrees[1], filterSpanWithinTree: null, includeEarlierStages: true)
                .Verify(
                    // (4,35): warning CS8618: Non-nullable field 'Value2' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                    //     public static readonly string Value2; // 1
                    Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Value2").WithArguments("field", "Value2").WithLocation(4, 35));

            comp.VerifyDiagnostics(
                // (4,35): warning CS8618: Non-nullable field 'Value2' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     public static readonly string Value2; // 1
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Value2").WithArguments("field", "Value2").WithLocation(4, 35));
        }

        [Fact]
        [WorkItem(1090263, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/1090263")]
        public void PropertyNoGetter()
        {
            var comp = CreateCompilation(@"
using System;
class C
{
    public string P { }
    public string P2 { set { } }
    public string P3 { } = string.Empty;
    public C()
    {
        P = """";
        Console.WriteLine(P2);
        P2 += """";
    }
}", options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (5,19): error CS0548: 'C.P': property or indexer must have at least one accessor
                //     public string P { }
                Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "P").WithArguments("C.P").WithLocation(5, 19),
                // (7,19): error CS8050: Only auto-implemented properties, or properties that use the 'field' keyword, can have initializers.
                //     public string P3 { } = string.Empty;
                Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P3").WithLocation(7, 19),
                // (7,19): error CS0548: 'C.P3': property or indexer must have at least one accessor
                //     public string P3 { } = string.Empty;
                Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "P3").WithArguments("C.P3").WithLocation(7, 19),
                // (10,9): error CS0200: Property or indexer 'C.P' cannot be assigned to -- it is read only
                //         P = "";
                Diagnostic(ErrorCode.ERR_AssgReadonlyProp, "P").WithArguments("C.P").WithLocation(10, 9),
                // (11,27): error CS0154: The property or indexer 'C.P2' cannot be used in this context because it lacks the get accessor
                //         Console.WriteLine(P2);
                Diagnostic(ErrorCode.ERR_PropertyLacksGet, "P2").WithArguments("C.P2").WithLocation(11, 27),
                // (12,9): error CS0154: The property or indexer 'C.P2' cannot be used in this context because it lacks the get accessor
                //         P2 += "";
                Diagnostic(ErrorCode.ERR_PropertyLacksGet, "P2").WithArguments("C.P2").WithLocation(12, 9)
            );
        }

        [Fact]
        public void MaybeNullT_Uninitialized()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
public class C<T>
{
    [MaybeNull] public T F;
    [MaybeNull] public T P { get; set; }
}";
            var comp = CreateCompilation(new[] { source, MaybeNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                );
        }

        [Fact]
        public void MaybeNull_ClassT_Uninitialized()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
public class C<T> where T : class
{
    [MaybeNull] public T F;
    [MaybeNull] public T P { get; set; }
}";
            var comp = CreateCompilation(new[] { source, MaybeNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                );
        }

        [Fact]
        public void MaybeNull_NotNullT_Uninitialized()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
public class C<T> where T : notnull
{
    [MaybeNull] public T F;
    [MaybeNull] public T P { get; set; }
}";
            var comp = CreateCompilation(new[] { source, MaybeNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                );
        }

        [Fact]
        public void MaybeNull_Uninitialized()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
public class C
{
    [MaybeNull] public string F;
    [MaybeNull] public string P { get; set; }
}";
            var comp = CreateCompilation(new[] { source, MaybeNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                );
        }

        [Fact]
        public void MaybeNull_NullInitializer()
        {
            var source =
@"using System.Diagnostics.CodeAnalysis;
public class C
{
    [MaybeNull] public string F = null;
    [MaybeNull] public string P { get; set; } = null;
}";
            var comp = CreateCompilation(new[] { source, MaybeNullAttributeDefinition }, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (4,35): warning CS8625: Cannot convert null literal to non-nullable reference type.
                //     [MaybeNull] public string F = null;
                Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(4, 35),
                // (5,49): warning CS8625: Cannot convert null literal to non-nullable reference type.
                //     [MaybeNull] public string P { get; set; } = null;
                Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(5, 49)
                );
        }

        [Fact]
        [WorkItem(58073, "https://github.com/dotnet/roslyn/issues/58073")]
        public void DiagnosticAdditionalLocations_SquiggleConstructor()
        {
            var source =
@"
public class C
{
    public C() { }

    public string S { get; }
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (4,12): warning CS8618: Non-nullable property 'S' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public C() { }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C").WithArguments("property", "S").WithLocation(4, 12));

            var property = comp.GetTypeByMetadataName("C").GetMember("S");
            var actualAdditionalLocations = comp.GetDiagnostics().Single().AdditionalLocations;
            Assert.Equal(property.Locations.Single(), actualAdditionalLocations.Single());
        }

        [Fact]
        [WorkItem(58073, "https://github.com/dotnet/roslyn/issues/58073")]
        public void DiagnosticAdditionalLocations_SquiggleProperty()
        {
            var source =
@"
public class C
{
    public string S { get; }
}";
            var comp = CreateCompilation(source, options: WithNullableEnable());
            comp.VerifyDiagnostics(
                // (4,19): warning CS8618: Non-nullable property 'S' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public string S { get; }
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "S").WithArguments("property", "S").WithLocation(4, 19));

            var property = comp.GetTypeByMetadataName("C").GetMember("S");
            var actualAdditionalLocations = comp.GetDiagnostics().Single().AdditionalLocations;
            Assert.Equal(property.Locations.Single(), actualAdditionalLocations.Single());
        }

        [Theory]
        [CombinatorialData]
        [WorkItem(66037, "https://github.com/dotnet/roslyn/issues/66037")]
        public void TestAdditionalLocationOnCompilerDiagnostic(bool warnAsError)
        {
            var options = WithNullableEnable();
            if (warnAsError)
            {
                options = options.WithGeneralDiagnosticOption(ReportDiagnostic.Error);
            }

            var comp = CreateCompilation(@"
public class B
{
    public B? f2;
}
public class C
{
    public B f;
    static void Main()
    {
        new C() { f = { f2 = null }};
    }
}", options: options);

            var diagnostics = comp.GetDiagnostics();
            diagnostics.Verify(
                // (8,14): warning CS8618: Non-nullable field 'f' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
                //     public B f;
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "f").WithArguments("field", "f").WithLocation(8, 14).WithWarningAsError(warnAsError));

            var diagnostic = Assert.Single(diagnostics);
            Assert.Single(diagnostic.AdditionalLocations);
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68346")]
        public void CopyConstructor_01()
        {
            var source = """
                #nullable enable
                var r = new Rec(); // to show that implicit parameterless ctor still exists, hence diagnostic 1

                record Rec
                {
                    public string Prop { get; init; } // 1
                    public Rec(Rec other) // 2
                    {
                    }
                }
                """;

            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition });
            comp.VerifyEmitDiagnostics(
                // 0.cs(6,19): warning CS8618: Non-nullable property 'Prop' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public string Prop { get; init; } // 1
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Prop").WithArguments("property", "Prop").WithLocation(6, 19),
                // 0.cs(7,12): warning CS8618: Non-nullable property 'Prop' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public Rec(Rec other) // 2
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Rec").WithArguments("property", "Prop").WithLocation(7, 12));
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68346")]
        public void CopyConstructor_02()
        {
            var source = """
                #nullable enable
                record Rec(string Prop)
                {
                    public Rec(Rec other) // 1
                    {
                    }
                }
                """;

            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition });
            comp.VerifyEmitDiagnostics(
                // 0.cs(4,12): warning CS8618: Non-nullable property 'Prop' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public Rec(Rec other) // 1
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Rec").WithArguments("property", "Prop").WithLocation(4, 12));
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68346")]
        public void CopyConstructor_03()
        {
            // copy constructor implicitly declared
            var source = """
                #nullable enable
                record Rec
                {
                    public required string Prop { get; init; }

                    public void M()
                    {
                        var rec = new Rec(this);
                    }
                }
                """;

            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition, RequiredMemberAttribute, SetsRequiredMembersAttribute, CompilerFeatureRequiredAttribute });
            comp.VerifyEmitDiagnostics();
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68346")]
        public void CopyConstructor_04()
        {
            // copy constructor explicitly declared, lacks SetsRequiredMembersAttribute
            var source = """
                #nullable enable
                record Rec
                {
                    public required string Prop { get; init; }
                    public Rec(Rec other) { }

                    public void M()
                    {
                        var rec = new Rec(this);
                    }
                }
                """;

            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition, RequiredMemberAttribute, SetsRequiredMembersAttribute, CompilerFeatureRequiredAttribute });
            comp.VerifyEmitDiagnostics(
                // 0.cs(9,23): error CS9035: Required member 'Rec.Prop' must be set in the object initializer or attribute constructor.
                //         var rec = new Rec(this);
                Diagnostic(ErrorCode.ERR_RequiredMemberMustBeSet, "Rec").WithArguments("Rec.Prop").WithLocation(9, 23));
        }

        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68346")]
        public void CopyConstructor_05()
        {
            // copy constructor explicitly declared, has SetsRequiredMembersAttribute
            var source = """
                using System.Diagnostics.CodeAnalysis;

                #nullable enable
                record Rec
                {
                    public required string Prop { get; init; }

                    [SetsRequiredMembers]
                    public Rec(Rec other) { } // 1

                    public void M()
                    {
                        var rec = new Rec(this);
                    }
                }
                """;

            var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition, RequiredMemberAttribute, SetsRequiredMembersAttribute, CompilerFeatureRequiredAttribute });
            comp.VerifyEmitDiagnostics(
                // 0.cs(9,12): warning CS8618: Non-nullable property 'Prop' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
                //     public Rec(Rec other) { } // 1
                Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "Rec").WithArguments("property", "Prop").WithLocation(9, 12));
        }
    }
}
