/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Semantic/Semantics/UninitializedNonNullableFieldTests.cs
2 933 строки
113 KB
Charles Stoner
Field-backed properties: update uses of IsAutoProperty (#74798)
27 авг 2024, 22:58
Не верифицирован
27 авг 2024, 22:58
b8c1ea0
Код
Авторство
О чём код?
// 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)); } } }