From f8560974122d1c86270f1ad57bd628a1e2d14b3e Mon Sep 17 00:00:00 2001 From: Alireza Habibi Date: Wed, 10 Nov 2021 22:22:46 +0330 Subject: [PATCH] The annotation on the output type is ignored --- .../CSharp/Portable/CSharpResources.resx | 9 +- .../CSharp/Portable/Errors/ErrorCode.cs | 2 + .../CSharp/Portable/Errors/ErrorFacts.cs | 2 + .../FlowAnalysis/NullableWalker_Patterns.cs | 13 ++ .../Generated/ErrorFacts.Generated.cs | 1 + .../Portable/xlf/CSharpResources.cs.xlf | 15 +- .../Portable/xlf/CSharpResources.de.xlf | 15 +- .../Portable/xlf/CSharpResources.es.xlf | 15 +- .../Portable/xlf/CSharpResources.fr.xlf | 15 +- .../Portable/xlf/CSharpResources.it.xlf | 15 +- .../Portable/xlf/CSharpResources.ja.xlf | 15 +- .../Portable/xlf/CSharpResources.ko.xlf | 15 +- .../Portable/xlf/CSharpResources.pl.xlf | 15 +- .../Portable/xlf/CSharpResources.pt-BR.xlf | 15 +- .../Portable/xlf/CSharpResources.ru.xlf | 15 +- .../Portable/xlf/CSharpResources.tr.xlf | 15 +- .../Portable/xlf/CSharpResources.zh-Hans.xlf | 15 +- .../Portable/xlf/CSharpResources.zh-Hant.xlf | 15 +- .../PatternMatchingTests_ListPatterns.cs | 212 +++++++++++------- 19 files changed, 290 insertions(+), 144 deletions(-) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 55c6e1119453e..0cd245a8239bc 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -6730,9 +6730,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ list pattern - - length pattern - List patterns may not be used for a value of type '{0}'. @@ -6893,4 +6890,10 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ newlines in interpolations + + The annotation on the output type '{0}' is ignored. + + + The annotation on the output type is ignored. + \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index ef95006b69848..3f2f4561806fc 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -2006,6 +2006,8 @@ internal enum ErrorCode ERR_UnsupportedTypeForSlicePattern, ERR_MisplacedSlicePattern, + WRN_AnnotationOnSliceReturnType = 8978, + #endregion // Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd) diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs index d5c89e8cb9535..bb3c402645f3d 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs @@ -80,6 +80,7 @@ static ErrorFacts() nullableWarnings.Add(GetId(ErrorCode.WRN_ParameterDisallowsNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_ParameterNotNullIfNotNull)); nullableWarnings.Add(GetId(ErrorCode.WRN_ReturnNotNullIfNotNull)); + nullableWarnings.Add(GetId(ErrorCode.WRN_AnnotationOnSliceReturnType)); NullableWarnings = nullableWarnings.ToImmutable(); } @@ -486,6 +487,7 @@ internal static int GetWarningLevel(ErrorCode code) case ErrorCode.WRN_InterpolatedStringHandlerArgumentAttributeIgnoredOnLambdaParameters: case ErrorCode.WRN_CompileTimeCheckedOverflow: case ErrorCode.WRN_MethGrpToNonDel: + case ErrorCode.WRN_AnnotationOnSliceReturnType: return 1; default: return 0; diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs index d075cb1f15a69..4121c041d6687 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs @@ -567,6 +567,7 @@ public PossiblyConditionalState Clone() var output = new BoundDagTemp(e.Syntax, type.Type, e); var outputSlot = makeDagTempSlot(type, output); Debug.Assert(outputSlot > 0); + ignoreAnnotationAndReport(outputSlot, type, ref this.State, e); addToTempMap(output, outputSlot, type.Type); break; } @@ -719,6 +720,18 @@ public PossiblyConditionalState Clone() nodeStateMap.Free(); return labelStateMap; + void ignoreAnnotationAndReport(int outputSlot, TypeWithAnnotations outputType, ref LocalState state, BoundDagSliceEvaluation e) + { + if (PossiblyNullableType(outputType.Type)) + { + if (state[outputSlot] == NullableFlowState.MaybeNull) + { + ReportDiagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, e.Syntax, outputType); + state[outputSlot] = NullableFlowState.NotNull; + } + } + } + void learnFromNonNullTest(int inputSlot, ref LocalState state) { if (stateWhenNotNullOpt is { } stateWhenNotNull && inputSlot == originalInputSlot) diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs index 8b71fa9ea7d54..ba552f7f92b2f 100644 --- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs @@ -279,6 +279,7 @@ public static bool IsWarning(ErrorCode code) case ErrorCode.WRN_InterpolatedStringHandlerArgumentAttributeIgnoredOnLambdaParameters: case ErrorCode.WRN_CompileTimeCheckedOverflow: case ErrorCode.WRN_MethGrpToNonDel: + case ErrorCode.WRN_AnnotationOnSliceReturnType: return true; default: return false; diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index e235fa592d778..9160ac3f14c73 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -1302,11 +1302,6 @@ návratový typ lambda - - length pattern - length pattern - - line span directive direktiva line span @@ -1372,6 +1367,16 @@ Načtené sestavení se odkazuje na architekturu .NET Framework, což se nepodporuje + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. Typ {0} nelze v tomto kontextu použít, protože se nedá reprezentovat v metadatech. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 94366330a38e5..483e00b20e9e9 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -1302,11 +1302,6 @@ Lambda-Rückgabetyp - - length pattern - length pattern - - line span directive Zeilenabstand-Anweisung @@ -1372,6 +1367,16 @@ Die geladene Assembly verweist auf das .NET Framework. Dies wird nicht unterstützt. + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. Der Typ "{0}" kann in diesem Kontext nicht verwendet werden, da er nicht in Metadaten dargestellt werden kann. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index e4e04e5379d81..6fa907c2d2dc0 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -1302,11 +1302,6 @@ tipo de valor devuelto de lambda - - length pattern - length pattern - - line span directive directiva de intervalo de línea @@ -1372,6 +1367,16 @@ El ensamblado que se ha cargado hace referencia a .NET Framework, lo cual no se admite. + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. El tipo "{0}" no se puede usar en este contexto porque no se puede representar en metadatos. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 46661eed773a7..64eed09835b64 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -1302,11 +1302,6 @@ type de retour lambda - - length pattern - length pattern - - line span directive directive de l’étendue de ligne @@ -1372,6 +1367,16 @@ L'assembly chargé référence le .NET Framework, ce qui n'est pas pris en charge. + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. Le type « {0} » ne peut pas être utilisé dans ce contexte, car il ne peut pas être représenté dans les métadonnées. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 6d8ebb5c6a1e6..c4c0d7a2c27ea 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -1302,11 +1302,6 @@ tipo restituito dell'espressione lambda - - length pattern - length pattern - - line span directive direttiva per intervallo di riga @@ -1372,6 +1367,16 @@ L'assembly caricato fa riferimento a .NET Framework, che non è supportato. + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. Non è possibile usare il tipo '{0}' in questo contesto perché non può essere rappresentato nei metadati. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 6fd2a3336b7a3..08ac3f093888a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -1302,11 +1302,6 @@ ラムダ戻り値の型 - - length pattern - length pattern - - line span directive line span ディレクティブ @@ -1372,6 +1367,16 @@ 読み込まれたアセンブリが .NET Framework を参照しています。これはサポートされていません。 + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. 型 '{0}' は、メタデータで表現できないため、このコンテキストでは使用できません。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 562dcc0cc6714..58578245812e6 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -1302,11 +1302,6 @@ 람다 반환 유형 - - length pattern - length pattern - - line span directive 라인 범위 지시문 @@ -1372,6 +1367,16 @@ 로드된 어셈블리가 지원되지 않는 .NET Framework를 참조합니다. + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. 유형 ‘{0}’은(는) 메타데이터로 표현할 수 없기 때문에 이 컨텍스트에서 사용할 수 없습니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 3b59cbb04f886..1633ae64b3d13 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -1302,11 +1302,6 @@ zwracany typ lambda - - length pattern - length pattern - - line span directive dyrektywa zakresu wierszy @@ -1372,6 +1367,16 @@ Załadowany zestaw odwołuje się do platformy .NET Framework, co nie jest obsługiwane. + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. Typ „{0}” nie może być używany w tym kontekście, ponieważ nie może być reprezentowany w metadanych. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index d6621ff5fdac7..91bbbd9ae49be 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -1302,11 +1302,6 @@ tipo de retorno de lambda - - length pattern - length pattern - - line span directive diretiva de extensão de linha @@ -1372,6 +1367,16 @@ O assembly carregado referencia o .NET Framework, mas não há suporte para isso. + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. O tipo '{0}' não pode ser usado neste contexto porque ele não pode ser representado em metadados. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 531352d18c1d0..09235478e8cac 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -1302,11 +1302,6 @@ тип возвращаемого значения лямбда - - length pattern - length pattern - - line span directive директива line span @@ -1372,6 +1367,16 @@ Загруженная сборка ссылается на платформу .NET Framework, которая не поддерживается. + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. Тип "{0}" нельзя использовать в этом контексте, так как он не может быть представлен в метаданных. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 5621cd051b9c0..5cb27154495af 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -1302,11 +1302,6 @@ lambda dönüş türü - - length pattern - length pattern - - line span directive satır aralığı yönergesi @@ -1372,6 +1367,16 @@ Yüklenen bütünleştirilmiş kod, desteklenmeyen .NET Framework'e başvuruyor. + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. Tür '{0}', meta verilerde temsili olmadığından bu bağlamda kullanılamaz. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 8002eb1133b5b..1e8b9590057fb 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -1302,11 +1302,6 @@ lambda 返回类型 - - length pattern - length pattern - - line span directive 行跨度指令 @@ -1372,6 +1367,16 @@ 加载的程序集引用了 .NET Framework,而此操作不受支持。 + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. 类型“{0}”不能在此上下文中使用,因为它不能在元数据中表示。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index ead099a94d8ef..9a4e31cfd7518 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -1302,11 +1302,6 @@ lambda 傳回型別 - - length pattern - length pattern - - line span directive line span 指示詞 @@ -1372,6 +1367,16 @@ 載入的組件參考了 .NET Framework,此情形不受支援。 + + The annotation on the output type '{0}' is ignored. + The annotation on the output type '{0}' is ignored. + + + + The annotation on the output type is ignored. + The annotation on the output type is ignored. + + Type '{0}' cannot be used in this context because it cannot be represented in metadata. 無法在此內容中使用類型 '{0}',因為它無法在中繼資料中表示。 diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_ListPatterns.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_ListPatterns.cs index 1105f2c8b236e..0343d8c528482 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_ListPatterns.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_ListPatterns.cs @@ -2620,13 +2620,13 @@ public void M() else rest.ToString(); // 1 - if (new C() is [1, ..var rest2]) - rest2.Value.ToString(); // 2 + if (new C() is [1, ..var rest2]) // ignored 2 + rest2.Value.ToString(); // 2 (no warning) else rest2.Value.ToString(); // 3, 4 - if (new C() is [1, ..var rest3]) - rest3.ToString(); // 5 + if (new C() is [1, ..var rest3]) // ignored 5 + rest3.ToString(); // 5 (no warning) else rest3.ToString(); // 6, 7 @@ -2638,9 +2638,9 @@ public void M() else rest4.ToString(); // 8, 9 - if (new C() is [1, ..var rest5]) + if (new C() is [1, ..var rest5]) // ignored 10 { - rest5.ToString(); // 10 + rest5.ToString(); // 10; (no warning) rest5 = default; } } @@ -2651,18 +2651,18 @@ public void M() // (14,13): error CS0165: Use of unassigned local variable 'rest' // rest.ToString(); // 1 Diagnostic(ErrorCode.ERR_UseDefViolation, "rest").WithArguments("rest").WithLocation(14, 13), - // (17,13): warning CS8629: Nullable value type may be null. - // rest2.Value.ToString(); // 2 - Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "rest2").WithLocation(17, 13), + // (16,36): warning CS8978: The annotation on the output type 'int?' is ignored. + // if (new C() is [1, ..var rest2]) // ignored 2 + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "var rest2").WithArguments("int?").WithLocation(16, 36), // (19,13): warning CS8629: Nullable value type may be null. // rest2.Value.ToString(); // 3, 4 Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "rest2").WithLocation(19, 13), // (19,13): error CS0165: Use of unassigned local variable 'rest2' // rest2.Value.ToString(); // 3, 4 Diagnostic(ErrorCode.ERR_UseDefViolation, "rest2").WithArguments("rest2").WithLocation(19, 13), - // (22,13): warning CS8602: Dereference of a possibly null reference. - // rest3.ToString(); // 5 - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "rest3").WithLocation(22, 13), + // (21,39): warning CS8978: The annotation on the output type 'string?' is ignored. + // if (new C() is [1, ..var rest3]) // ignored 5 + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "var rest3").WithArguments("string?").WithLocation(21, 39), // (24,13): warning CS8602: Dereference of a possibly null reference. // rest3.ToString(); // 6, 7 Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "rest3").WithLocation(24, 13), @@ -2675,9 +2675,9 @@ public void M() // (32,13): error CS0165: Use of unassigned local variable 'rest4' // rest4.ToString(); // 8, 9 Diagnostic(ErrorCode.ERR_UseDefViolation, "rest4").WithArguments("rest4").WithLocation(32, 13), - // (36,13): warning CS8602: Dereference of a possibly null reference. - // rest5.ToString(); // 10 - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "rest5").WithLocation(36, 13) + // (34,33): warning CS8978: The annotation on the output type 'T' is ignored. + // if (new C() is [1, ..var rest5]) // ignored 10 + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "var rest5").WithArguments("T").WithLocation(34, 33) ); var tree = compilation.SyntaxTrees.Single(); @@ -2700,7 +2700,7 @@ void verify(VarPatternSyntax declaration, string name, string expectedType) } [Fact] - public void SlicePattern_Nullability_NullableValue() + public void SlicePattern_Nullability_AnnotationIgnored() { var source = @" #nullable enable @@ -2721,13 +2721,13 @@ public void M() "; var compilation = CreateCompilation(source); compilation.VerifyEmitDiagnostics( - // (12,13): warning CS8602: Dereference of a possibly null reference. - // slice.ToString(); - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "slice").WithLocation(12, 13), - // (14,13): warning CS8602: Dereference of a possibly null reference. - // list.ToString(); - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "list").WithLocation(14, 13) - ); + // (11,27): warning CS8978: The annotation on the output type 'int[]?' is ignored. + // if (this is [1, ..var slice]) + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "var slice").WithArguments("int[]?").WithLocation(11, 27), + // (13,27): warning CS8978: The annotation on the output type 'int[]?' is ignored. + // if (this is [1, ..[] list]) + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "[] list").WithArguments("int[]?").WithLocation(13, 27) + ); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false); @@ -2772,13 +2772,13 @@ public void M() else rest.ToString(); // 1 - if (new C() is [1, ..var rest2]) - rest2.Value.ToString(); // 2 + if (new C() is [1, ..var rest2]) // ignored 2 + rest2.Value.ToString(); // 2 (no warning) else rest2.Value.ToString(); // 3, 4 - if (new C() is [1, ..var rest3]) - rest3.ToString(); // 5 + if (new C() is [1, ..var rest3]) // ignored 5 + rest3.ToString(); // 5 (no warning) else rest3.ToString(); // 6, 7 @@ -2797,18 +2797,18 @@ public void M() // (15,13): error CS0165: Use of unassigned local variable 'rest' // rest.ToString(); // 1 Diagnostic(ErrorCode.ERR_UseDefViolation, "rest").WithArguments("rest").WithLocation(15, 13), - // (18,13): warning CS8629: Nullable value type may be null. - // rest2.Value.ToString(); // 2 - Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "rest2").WithLocation(18, 13), + // (17,36): warning CS8978: The annotation on the output type 'int?' is ignored. + // if (new C() is [1, ..var rest2]) // ignored 2 + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "var rest2").WithArguments("int?").WithLocation(17, 36), // (20,13): warning CS8629: Nullable value type may be null. // rest2.Value.ToString(); // 3, 4 Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "rest2").WithLocation(20, 13), // (20,13): error CS0165: Use of unassigned local variable 'rest2' // rest2.Value.ToString(); // 3, 4 Diagnostic(ErrorCode.ERR_UseDefViolation, "rest2").WithArguments("rest2").WithLocation(20, 13), - // (23,13): warning CS8602: Dereference of a possibly null reference. - // rest3.ToString(); // 5 - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "rest3").WithLocation(23, 13), + // (22,39): warning CS8978: The annotation on the output type 'string?' is ignored. + // if (new C() is [1, ..var rest3]) // ignored 5 + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "var rest3").WithArguments("string?").WithLocation(22, 39), // (25,13): warning CS8602: Dereference of a possibly null reference. // rest3.ToString(); // 6, 7 Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "rest3").WithLocation(25, 13), @@ -3413,12 +3413,30 @@ public void M() "; var compilation = CreateCompilation(new[] { source, TestSources.Index, TestSources.Range }); compilation.VerifyEmitDiagnostics( + // (16,17): warning CS8978: The annotation on the output type 'object?' is ignored. + // [.. null] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null").WithArguments("object?").WithLocation(16, 17), // (20,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '[.. null, _]' is not covered. // _ = this switch // no tests for [.. null, _] Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("[.. null, _]").WithLocation(20, 18), + // (24,17): warning CS8978: The annotation on the output type 'object?' is ignored. + // [.. not null] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "not null").WithArguments("object?").WithLocation(24, 17), // (27,18): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '[.. not null, _]' is not covered. // _ = this switch // no test for [.. not null, _] - Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("[.. not null, _]").WithLocation(27, 18) + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("[.. not null, _]").WithLocation(27, 18), + // (31,17): warning CS8978: The annotation on the output type 'object?' is ignored. + // [.. null] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null").WithArguments("object?").WithLocation(31, 17), + // (38,17): warning CS8978: The annotation on the output type 'object?' is ignored. + // [.. not null] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "not null").WithArguments("object?").WithLocation(38, 17), + // (46,17): warning CS8978: The annotation on the output type 'object?' is ignored. + // [.. null] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null").WithArguments("object?").WithLocation(46, 17), + // (54,23): warning CS8978: The annotation on the output type 'object?' is ignored. + // [null, .. null] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null").WithArguments("object?").WithLocation(54, 23) ); } @@ -3456,7 +3474,10 @@ class D compilation.VerifyEmitDiagnostics( // (12,18): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '_' is not covered. // _ = this switch - Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("_").WithLocation(12, 18) + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("_").WithLocation(12, 18), + // (17,17): warning CS8978: The annotation on the output type 'D?' is ignored. + // [.. null] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null").WithArguments("D?").WithLocation(17, 17) ); } @@ -3549,27 +3570,60 @@ public void M() // Note: we don't try to explain nested slice patterns right now so all these just produce a fallback example var compilation = CreateCompilation(new[] { source, TestSources.Index, TestSources.Range }); compilation.VerifyEmitDiagnostics( - // (27,18): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '_' is not covered. - // _ = this switch // didn't test for [.. [not null]] // // 2 - Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("_").WithLocation(27, 18), - // (33,18): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '_' is not covered. - // _ = this switch // didn't test for [.. [not null]] // // 3 - Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("_").WithLocation(33, 18), - // (40,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. - // _ = this switch // didn't test for [.. null, _] // we're trying to construct an example with Length=1, the slice may not be null // 4 - Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(40, 18), - // (46,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. - // _ = this switch // didn't test for [_, .. null, _, _, _] // we're trying to construct an example with Length=4, the slice may not be null // 5 - Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(46, 18), - // (58,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. - // _ = this switch // didn't test for [_, .. [_, null], _] // 7 - Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(58, 18), - // (64,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. - // _ = this switch // didn't test for [_, .. [_, null], _, _] // 8 - Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(64, 18), - // (70,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. - // _ = this switch // didn't test for [_, .. [_, null, _], _] // 9 - Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(70, 18) + // (15,17): warning CS8978: The annotation on the output type 'C?' is ignored. + // [.. null] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null").WithArguments("C?").WithLocation(15, 17), + // (23,17): warning CS8978: The annotation on the output type 'C?' is ignored. + // [.. [null]] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "[null]").WithArguments("C?").WithLocation(23, 17), + // (27,18): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '_' is not covered. + // _ = this switch // didn't test for [.. [not null]] // // 2 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("_").WithLocation(27, 18), + // (30,17): warning CS8978: The annotation on the output type 'C?' is ignored. + // [.. [null]] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "[null]").WithArguments("C?").WithLocation(30, 17), + // (33,18): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '_' is not covered. + // _ = this switch // didn't test for [.. [not null]] // // 3 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("_").WithLocation(33, 18), + // (36,17): warning CS8978: The annotation on the output type 'C?' is ignored. + // [.. null] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null").WithArguments("C?").WithLocation(36, 17), + // (40,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. + // _ = this switch // didn't test for [.. null, _] // we're trying to construct an example with Length=1, the slice may not be null // 4 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(40, 18), + // (43,17): warning CS8978: The annotation on the output type 'C?' is ignored. + // [.. [not null]] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "[not null]").WithArguments("C?").WithLocation(43, 17), + // (46,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. + // _ = this switch // didn't test for [_, .. null, _, _, _] // we're trying to construct an example with Length=4, the slice may not be null // 5 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(46, 18), + // (49,20): warning CS8978: The annotation on the output type 'C?' is ignored. + // [_, .. [_, not null], _] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "[_, not null]").WithArguments("C?").WithLocation(49, 20), + // (55,20): warning CS8978: The annotation on the output type 'C?' is ignored. + // [_, .. [_, _], _] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "[_, _]").WithArguments("C?").WithLocation(55, 20), + // (58,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. + // _ = this switch // didn't test for [_, .. [_, null], _] // 7 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(58, 18), + // (61,20): warning CS8978: The annotation on the output type 'C?' is ignored. + // [_, .. null or [_, not null], _] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null or [_, not null]").WithArguments("C?").WithLocation(61, 20), + // (64,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. + // _ = this switch // didn't test for [_, .. [_, null], _, _] // 8 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(64, 18), + // (67,20): warning CS8978: The annotation on the output type 'C?' is ignored. + // [_, .. null or [_, not null], _, _] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null or [_, not null]").WithArguments("C?").WithLocation(67, 20), + // (70,18): warning CS8655: The switch expression does not handle some null inputs (it is not exhaustive). For example, the pattern '_' is not covered. + // _ = this switch // didn't test for [_, .. [_, null, _], _] // 9 + Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull, "switch").WithArguments("_").WithLocation(70, 18), + // (73,20): warning CS8978: The annotation on the output type 'C?' is ignored. + // [_, .. null or [_, not null, _], _] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "null or [_, not null, _]").WithArguments("C?").WithLocation(73, 20), + // (79,17): warning CS8978: The annotation on the output type 'C?' is ignored. + // [.. { Length: 1 }] => 0, + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "{ Length: 1 }").WithArguments("C?").WithLocation(79, 17) ); } @@ -4947,17 +5001,17 @@ void Test(int[] a) { Length: not 1 } => 0, [<0, ..] => 0, [..[>= 0]] => 1, - [_] => 2, // unreachable 2 + [_] => 2, // unreachable 2 }; } }" + TestSources.GetSubArray; var comp = CreateCompilationWithIndexAndRange(src); comp.VerifyEmitDiagnostics( // (11,13): error CS8510: The pattern is unreachable. It has already been handled by a previous arm of the switch expression or it is impossible to match. - // [_] => 2, // unreachable + // [_] => 2, // unreachable 1 Diagnostic(ErrorCode.ERR_SwitchArmSubsumed, "[_]").WithLocation(11, 13), // (18,13): error CS8510: The pattern is unreachable. It has already been handled by a previous arm of the switch expression or it is impossible to match. - // [_] => 2, + // [_] => 2, // unreachable 2 Diagnostic(ErrorCode.ERR_SwitchArmSubsumed, "[_]").WithLocation(18, 13) ); @@ -5000,7 +5054,7 @@ void Test(int[] a) { Length: not 1 } => 0, [<0, ..] => 0, [..[>= 0]] => 1, - [_] => 2, // unreachable 2 + [_] => 2, // unreachable 2 }` ", index: 1) ); @@ -5449,14 +5503,11 @@ void Test(int[] a) "); } - [Theory] - [PairwiseData] - public void Subsumption_Slice_00( - [CombinatorialRange(0, 18)] int c1, - [CombinatorialRange(0, 18)] int c2, - [CombinatorialValues("System.Span", "int[]")] string type) + [Fact] + public void Subsumption_Slice_00() { - var cases = new string[18] + const int Count = 18; + var cases = new string[Count] { "[1,2,3]", "[1,2,3,..[]]", @@ -5478,10 +5529,14 @@ public void Subsumption_Slice_00( "[1, ..[2, ..[], 3]]" }; - var case1 = cases[c1]; - var case2 = cases[c2]; + var r = new Random(); + for (int i = 0; i < 50; i++) + { + var case1 = cases[r.Next(Count)]; + var case2 = cases[r.Next(Count)]; + var type = r.Next(2) == 0 ? "System.Span" : "int[]"; - var src = @" + var src = @" class C { void Test(" + type + @" a) @@ -5494,11 +5549,12 @@ void Test(" + type + @" a) } } }"; - var comp = CreateCompilationWithIndexAndRangeAndSpan(new[] { src, TestSources.GetSubArray }, parseOptions: TestOptions.RegularWithListPatterns); - comp.VerifyEmitDiagnostics( - // (9,18): error CS8120: The switch case is unreachable. It has already been handled by a previous case or it is impossible to match. - Diagnostic(ErrorCode.ERR_SwitchCaseSubsumed, case2).WithLocation(9, 18) - ); + var comp = CreateCompilationWithIndexAndRangeAndSpan(new[] { src, TestSources.GetSubArray }, parseOptions: TestOptions.RegularWithListPatterns); + comp.VerifyEmitDiagnostics( + // (9,18): error CS8120: The switch case is unreachable. It has already been handled by a previous case or it is impossible to match. + Diagnostic(ErrorCode.ERR_SwitchCaseSubsumed, case2).WithLocation(9, 18) + ); + } } [Fact] @@ -5958,7 +6014,11 @@ public static void Print(ConsList? list) "; // Note: this pattern doesn't work well because list-patterns needs a functional Length var compilation = CreateCompilation(new[] { source, TestSources.Index, TestSources.Range, IsExternalInitTypeDefinition }); - compilation.VerifyDiagnostics(); + compilation.VerifyDiagnostics( + // (17,32): warning CS8978: The annotation on the output type 'ConsList?' is ignored. + // case [var head, .. var tail]: + Diagnostic(ErrorCode.WRN_AnnotationOnSliceReturnType, "var tail").WithArguments("ConsList?").WithLocation(17, 32) + ); var verifier = CompileAndVerify(compilation, verify: Verification.Fails); verifier.VerifyIL("ConsList.Print", @" {