From 7fdcc97a4d8e440f32c4d4f1542dc1f38ade9ddd Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Tue, 17 Sep 2019 11:13:39 -0700 Subject: [PATCH] Don't warn about empty initializers on nullable properties in object initializers (#38642) --- .../Portable/CSharpResources.Designer.cs | 18 ++ .../CSharp/Portable/CSharpResources.resx | 6 + .../CSharp/Portable/Errors/ErrorCode.cs | 1 + .../CSharp/Portable/Errors/ErrorFacts.cs | 2 + .../Portable/FlowAnalysis/NullableWalker.cs | 7 +- .../Generated/ErrorFacts.Generated.cs | 1 + .../Portable/xlf/CSharpResources.cs.xlf | 10 + .../Portable/xlf/CSharpResources.de.xlf | 10 + .../Portable/xlf/CSharpResources.es.xlf | 10 + .../Portable/xlf/CSharpResources.fr.xlf | 10 + .../Portable/xlf/CSharpResources.it.xlf | 10 + .../Portable/xlf/CSharpResources.ja.xlf | 10 + .../Portable/xlf/CSharpResources.ko.xlf | 10 + .../Portable/xlf/CSharpResources.pl.xlf | 10 + .../Portable/xlf/CSharpResources.pt-BR.xlf | 10 + .../Portable/xlf/CSharpResources.ru.xlf | 10 + .../Portable/xlf/CSharpResources.tr.xlf | 10 + .../Portable/xlf/CSharpResources.zh-Hans.xlf | 10 + .../Portable/xlf/CSharpResources.zh-Hant.xlf | 10 + .../Semantics/NullableReferenceTypesTests.cs | 185 ++++++++++++++++-- .../Test/Syntax/Diagnostics/DiagnosticTest.cs | 1 + 21 files changed, 330 insertions(+), 21 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs index 59bddff89d3..91aac1d9a54 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -15790,6 +15790,24 @@ internal class CSharpResources { } } + /// + /// Looks up a localized string similar to Object or collection initializer implicitly dereferences possibly null member '{0}'.. + /// + internal static string WRN_NullReferenceInitializer { + get { + return ResourceManager.GetString("WRN_NullReferenceInitializer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Object or collection initializer implicitly dereferences possibly null member.. + /// + internal static string WRN_NullReferenceInitializer_Title { + get { + return ResourceManager.GetString("WRN_NullReferenceInitializer_Title", resourceCulture); + } + } + /// /// Looks up a localized string similar to Possible null reference assignment to iteration variable. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 49d678f6ccd..e703a7ba8e6 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -5753,6 +5753,12 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + Object or collection initializer implicitly dereferences possibly null member. + Expression tree cannot contain value of ref struct or restricted type '{0}'. diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 6b8672cf9d0..e5d2405fbf9 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1706,6 +1706,7 @@ internal enum ErrorCode WRN_NullabilityMismatchInConstraintsOnPartialImplementation = 8667, ERR_NullableDirectiveTargetExpected = 8668, WRN_MissingNonNullTypesContextForAnnotationInGeneratedCode = 8669, + WRN_NullReferenceInitializer = 8670, ERR_MultipleAnalyzerConfigsInSameDir = 8700, diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs index 3a5cd9af9c9..5fc249c7c3a 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs @@ -63,6 +63,7 @@ static ErrorFacts() builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase)); builder.Add(getId(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList)); builder.Add(getId(ErrorCode.WRN_NullabilityMismatchInConstraintsOnPartialImplementation)); + builder.Add(getId(ErrorCode.WRN_NullReferenceInitializer)); NullableWarnings = builder.ToImmutable(); @@ -430,6 +431,7 @@ internal static int GetWarningLevel(ErrorCode code) case ErrorCode.WRN_UndecoratedCancellationTokenParameter: case ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint: case ErrorCode.WRN_DisallowNullAttributeForbidsMaybeNullAssignment: + case ErrorCode.WRN_NullReferenceInitializer: return 1; default: return 0; diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index d64965ed60d..9b4860a262a 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -1836,9 +1836,12 @@ private void VisitObjectCreationInitializer(Symbol containingSymbol, int contain void checkImplicitReceiver() { - if (containingSlot >= 0) + if (containingSlot >= 0 && (node as BoundObjectInitializerExpressionBase)?.Initializers.Length != 0) { - _ = ReportPossibleNullReceiverIfNeeded(node.Type, this.State[containingSlot], checkNullableValueType: false, node.Syntax, out _); + if (!node.Type.IsValueType && State[containingSlot].MayBeNull()) + { + ReportDiagnostic(ErrorCode.WRN_NullReferenceInitializer, node.Syntax, containingSymbol); + } } } } diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs index 98754f1966d..7eaa7dc4cde 100644 --- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs @@ -229,6 +229,7 @@ public static bool IsWarning(ErrorCode code) case ErrorCode.WRN_ImplicitCopyInReadOnlyMember: case ErrorCode.WRN_NullabilityMismatchInConstraintsOnPartialImplementation: case ErrorCode.WRN_MissingNonNullTypesContextForAnnotationInGeneratedCode: + case ErrorCode.WRN_NullReferenceInitializer: case ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint: return true; default: diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index f165fabf724..9f560c7c758 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -1492,6 +1492,16 @@ Může jít o přiřazení s odkazem null. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable Možné přiřazení odkazu s hodnotou null k proměnné iterace diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 852981fc7c5..cb0e48a9a2c 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -1492,6 +1492,16 @@ Mögliche Nullverweiszuweisung. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable Mögliche Zuweisung eines Nullverweises zu Iterationsvariable diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index b7efafe3600..03f2fbae61b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -1492,6 +1492,16 @@ Posible asignación de referencia nula + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable Posible asignación de referencia de tipo NULL a variable de iteración diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 477032a970d..ce3530eba78 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -1492,6 +1492,16 @@ Existence possible d'une assignation de référence null. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable Affectation d'une éventuelle référence null à la variable d'itération diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 408c6793e27..6459a03a38f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -1492,6 +1492,16 @@ Possibile assegnazione di riferimento Null. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable Possibile assegnazione di riferimento Null alla variabile di iterazione diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index e0b8758b175..0a3457f346a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -1492,6 +1492,16 @@ Null 参照割り当ての可能性があります。 + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable 繰り返し変数に対する null 参照代入の可能性があります diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 2c2beac145b..df78fc31298 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -1492,6 +1492,16 @@ 가능한 null 참조 할당입니다. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable 반복 변수에 대한 가능한 null 참조 할당 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 098d699b4b9..620fbc39c55 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -1492,6 +1492,16 @@ Możliwe przypisanie odwołania o wartości null. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable Możliwe przypisanie odwołania o wartości null do zmiennej iteracji diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 9f894e3a8cf..5d585896e6a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -1492,6 +1492,16 @@ Possível atribuição de referência nula. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable Possível atribuição de referência nula à variável de iteração diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index ac5ef82032b..62532f207ea 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -1492,6 +1492,16 @@ Возможно, присваивание-ссылка, допускающее значение NULL. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable Назначение вероятной пустой ссылки переменной итерации diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 7dba593d593..b5631306682 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -1492,6 +1492,16 @@ Olası null başvuru ataması. + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable Yineleme değişkenine olası null başvuru ataması diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 900ae6464ec..b77984c6fd7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -1492,6 +1492,16 @@ 可能的 null 引用赋值。 + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable 迭代变量的可能的空引用赋值 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 7240ea06c21..03cbb99a164 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -1492,6 +1492,16 @@ 可能有 Null 參考指派。 + + Object or collection initializer implicitly dereferences possibly null member '{0}'. + Object or collection initializer implicitly dereferences possibly null member '{0}'. + + + + Object or collection initializer implicitly dereferences possibly null member. + Object or collection initializer implicitly dereferences possibly null member. + + Possible null reference assignment to iteration variable 反覆運算變數的可能 null 參考指派 diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index ef78fb1d5fa..a458b50ff95 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -307,15 +307,166 @@ public class C public B? f; static void Main() { - new C() { f = { f2 = null, f3 = null }}; + new C() { f = { f2 = null, f3 = null }}; // 1 } }", options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( - // (12,23): warning CS8602: Dereference of a possibly null reference. - // new C() { f = { f2 = null, f3 = null }}; - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "{ f2 = null, f3 = null }").WithLocation(12, 23) - ); + // (12,23): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.f'. + // new C() { f = { f2 = null, f3 = null }}; // 1 + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ f2 = null, f3 = null }").WithArguments("C.f").WithLocation(12, 23)); + } + + [Fact, WorkItem(32495, "https://github.com/dotnet/roslyn/issues/32495")] + public void CheckImplicitObjectInitializerReceiver_Generic() + { + var comp = CreateCompilation(@" +public interface IB +{ + object? f2 { get; set; } + object? f3 { get; set; } +} + +public struct StructB : IB +{ + public object? f2 { get; set; } + public object? f3 { get; set; } +} + +public class ClassB : IB +{ + public object? f2 { get; set; } + public object? f3 { get; set; } +} + +public class C where T : IB? +{ + public T f = default!; + static void Main() + { + new C() { f = { f2 = null, f3 = null }}; // 1 + new C() { f = { f2 = null, f3 = null }}; + new C() { f = { f2 = null, f3 = null }}; // 2 + new C() { f = { f2 = null, f3 = null }}; + } +}", options: WithNonNullTypesTrue()); + + comp.VerifyDiagnostics( + // (25,26): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.f'. + // new C() { f = { f2 = null, f3 = null }}; // 1 + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ f2 = null, f3 = null }").WithArguments("C.f").WithLocation(25, 26), + // (27,32): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.f'. + // new C() { f = { f2 = null, f3 = null }}; // 2 + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ f2 = null, f3 = null }").WithArguments("C.f").WithLocation(27, 32)); + } + + [Fact, WorkItem(38060, "https://github.com/dotnet/roslyn/issues/38060")] + public void CheckImplicitObjectInitializerReceiver_EmptyInitializers() + { + var comp = CreateCompilation(@" +public class B { } +public class C +{ + public B? f; + static void Main() + { + new C() { f = { }}; + } +}", options: WithNonNullTypesTrue()); + + comp.VerifyDiagnostics(); + } + + [Fact, WorkItem(32495, "https://github.com/dotnet/roslyn/issues/32495")] + public void CheckImplicitObjectInitializerReceiver_CollectionInitializer() + { + var comp = CreateCompilation(@" +using System.Collections; + +public class B : IEnumerable +{ + public void Add(object o) { } + public IEnumerator GetEnumerator() => null!; +} + +public class C +{ + public B? f; + static void Main() + { + new C() { f = { new object(), new object() }}; // 1 + } +}", options: WithNonNullTypesTrue()); + + comp.VerifyDiagnostics( + // (15,23): warning CS8670: Object or collection initializer implicitly dereferences nullable member 'C.f'. + // new C() { f = { new object(), new object() }}; // 1 + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ new object(), new object() }").WithArguments("C.f").WithLocation(15, 23)); + } + + [Fact, WorkItem(32495, "https://github.com/dotnet/roslyn/issues/32495")] + public void CheckImplicitObjectInitializerReceiver_CollectionInitializer_Generic() + { + var comp = CreateCompilation(@" +using System.Collections; + +public interface IAddable : IEnumerable +{ + void Add(object o); +} + +public class ClassAddable : IAddable +{ + public void Add(object o) { } + public IEnumerator GetEnumerator() => null!; +} + +public struct StructAddable : IAddable +{ + public void Add(object o) { } + public IEnumerator GetEnumerator() => null!; +} + + +public class C where T : IAddable? +{ + public T f = default!; + static void Main() + { + new C() { f = { new object(), new object() }}; // 1 + new C() { f = { new object(), new object() }}; + new C() { f = { new object(), new object() }}; // 2 + new C() { f = { new object(), new object() }}; + } +}", options: WithNonNullTypesTrue()); + + comp.VerifyDiagnostics( + // (27,26): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.f'. + // new C() { f = { new object(), new object() }}; // 1 + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ new object(), new object() }").WithArguments("C.f").WithLocation(27, 26), + // (29,38): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.f'. + // new C() { f = { new object(), new object() }}; // 2 + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ new object(), new object() }").WithArguments("C.f").WithLocation(29, 38)); + } + + [Fact, WorkItem(38060, "https://github.com/dotnet/roslyn/issues/38060")] + public void CheckImplicitObjectInitializerReceiver_EmptyCollectionInitializer() + { + var comp = CreateCompilation(@" +public class B +{ + void Add(object o) { } +} +public class C +{ + public B? f; + static void Main() + { + new C() { f = { }}; + } +}", options: WithNonNullTypesTrue()); + + comp.VerifyDiagnostics(); } [Fact, WorkItem(32495, "https://github.com/dotnet/roslyn/issues/32495")] @@ -382,10 +533,9 @@ static void Main() }", options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( - // (10,25): warning CS8602: Dereference of a possibly null reference. + // (10,25): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.this[int]'. // new C() { [0] = { f2 = null }}; - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "{ f2 = null }").WithLocation(10, 25) - ); + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ f2 = null }").WithArguments("C.this[int]").WithLocation(10, 25)); } [Fact, WorkItem(32495, "https://github.com/dotnet/roslyn/issues/32495")] @@ -407,13 +557,12 @@ static void Main() }", options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( - // (12,24): warning CS8602: Dereference of a possibly null reference. + // (12,24): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.fc'. // new C() { fc = { fb = { f2 = null} }}; - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "{ fb = { f2 = null} }").WithLocation(12, 24), - // (12,31): warning CS8602: Dereference of a possibly null reference. + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ fb = { f2 = null} }").WithArguments("C.fc").WithLocation(12, 24), + // (12,31): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.fb'. // new C() { fc = { fb = { f2 = null} }}; - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "{ f2 = null}").WithLocation(12, 31) - ); + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ f2 = null}").WithArguments("C.fb").WithLocation(12, 31)); } [Fact, WorkItem(32495, "https://github.com/dotnet/roslyn/issues/32495")] @@ -434,10 +583,9 @@ static void Main() }", options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( - // (11,23): warning CS8602: Dereference of a possibly null reference. + // (11,23): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.f'. // new C() { f = { [0] = null }}; - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "{ [0] = null }").WithLocation(11, 23) - ); + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ [0] = null }").WithArguments("C.f").WithLocation(11, 23)); } [Fact, WorkItem(32495, "https://github.com/dotnet/roslyn/issues/32495")] @@ -460,10 +608,9 @@ static void Main() }", options: WithNonNullTypesTrue()); comp.VerifyDiagnostics( - // (13,23): warning CS8602: Dereference of a possibly null reference. + // (13,23): warning CS8670: Object or collection initializer implicitly dereferences possibly null member 'C.f'. // new C() { f = { 1 }}; - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "{ 1 }").WithLocation(13, 23) - ); + Diagnostic(ErrorCode.WRN_NullReferenceInitializer, "{ 1 }").WithArguments("C.f").WithLocation(13, 23)); } [Fact, WorkItem(29964, "https://github.com/dotnet/roslyn/issues/29964")] diff --git a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs index 3cb76b651fd..edcf4ae1f22 100644 --- a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs +++ b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs @@ -309,6 +309,7 @@ public void WarningLevel_2() case ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull: case ErrorCode.WRN_ImplicitCopyInReadOnlyMember: case ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint: + case ErrorCode.WRN_NullReferenceInitializer: Assert.Equal(1, ErrorFacts.GetWarningLevel(errorCode)); break; case ErrorCode.WRN_InvalidVersionFormat: -- GitLab