未验证 提交 2ad1435f 编写于 作者: N Neal Gafter 提交者: GitHub

Fix a crash when a nullable reference type is used in a pattern. (#45206)

Fixes #45103
上级 88dd4bb5
......@@ -399,10 +399,15 @@ private BoundPattern BindDiscardPattern(DiscardPatternSyntax node, TypeSymbol in
diagnostics.Add(ErrorCode.ERR_PointerTypeInPatternMatching, typeSyntax.Location);
return true;
}
else if (patternType.IsNullableType() || typeSyntax is NullableTypeSyntax)
else if (patternType.IsNullableType())
{
// It is an error to use pattern-matching with a nullable type, because you'll never get null. Use the underlying type.
Error(diagnostics, ErrorCode.ERR_PatternNullableType, typeSyntax, patternType, patternType.GetNullableUnderlyingType());
Error(diagnostics, ErrorCode.ERR_PatternNullableType, typeSyntax, patternType.GetNullableUnderlyingType());
return true;
}
else if (typeSyntax is NullableTypeSyntax)
{
Error(diagnostics, ErrorCode.ERR_PatternNullableType, typeSyntax, patternType);
return true;
}
else if (patternType.IsStatic)
......
......@@ -5060,7 +5060,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<value>Combined length of user strings used by the program exceeds allowed limit. Try to decrease use of string literals.</value>
</data>
<data name="ERR_PatternNullableType" xml:space="preserve">
<value>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</value>
<value>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</value>
</data>
<data name="ERR_IsNullableType" xml:space="preserve">
<value>It is not legal to use nullable reference type '{0}?' in an is-type expression; use the underlying type '{0}' instead.</value>
......
......@@ -9766,8 +9766,8 @@ Pokud chcete odstranit toto varování, můžete místo toho použít /reference
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">Ve vzoru se nepovoluje použití typu s možnou hodnotou null {0}; místo toho použijte základní typ {1}.</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ Um die Warnung zu beheben, können Sie stattdessen /reference verwenden (Einbett
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">Es ist unzulässig, den Nullable-Typ "{0}" in einem Muster zu verwenden. Verwenden Sie stattdessen den zugrunde liegenden Typ "{1}".</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ Para eliminar la advertencia puede usar /reference (establezca la propiedad Embe
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">No se puede usar el tipo '{0}' que acepta valores NULL en un patrón; utilice el tipo '{1}' subyacente.</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ Pour supprimer l'avertissement, vous pouvez utiliser la commande /reference (dé
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">Il n'est pas correct d'utiliser le type Nullable '{0}' dans un modèle. Utilisez le type sous-jacent '{1}' à la place.</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ Per rimuovere l'avviso, è invece possibile usare /reference (impostare la propr
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">Non è consentito usare il tipo nullable '{0}' in un criterio. Usare il tipo sottostante '{1}'.</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">パターンで Null 許容型 '{0}' を使用することはできません。代わりに基になる型 '{1}' をご使用ください。</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">패턴에 nullable 형식 '{0}'을(를) 사용하는 것은 올바르지 않습니다. 대신 기본 형식 '{1}'을(를) 사용하세요.</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ Aby usunąć ostrzeżenie, możesz zamiast tego użyć opcji /reference (ustaw w
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">Użycie typu dopuszczającego wartość null „{0}” jest niedozwolone we wzorcu. Użyj zamiast tego bazowego typu „{1}”.</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9764,8 +9764,8 @@ Para incorporar informações de tipo de interoperabilidade para os dois assembl
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">É ilegal usar o tipo que permite valor nulo '{0}' em um padrão; em vez disso, use o tipo subjacente '{1}'.</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">Запрещено использовать тип "{0}", допускающий значение NULL, в шаблоне. Используйте вместо него базовый тип "{1}".</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ Uyarıyı kaldırmak için, /reference kullanabilirsiniz (Birlikte Çalışma T
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">Boş değer atanabilir '{0}' türünün bir desende kullanılması yasaktır; bunun yerine temel alınan '{1}' türünü kullanın.</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">在模式中使用可以为 null 的类型“{0}”是非法的;请改用基础类型“{1}”。</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -9766,8 +9766,8 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<note />
</trans-unit>
<trans-unit id="ERR_PatternNullableType">
<source>It is not legal to use nullable type '{0}' in a pattern; use the underlying type '{1}' instead.</source>
<target state="translated">在模式中使用可為 Null 的型別 '{0}' 不合法; 請改用基礎類型 '{1}'。</target>
<source>It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</source>
<target state="new">It is not legal to use nullable type '{0}?' in a pattern; use the underlying type '{0}' instead.</target>
<note />
</trans-unit>
<trans-unit id="ERR_PeWritingFailure">
......
......@@ -145,7 +145,7 @@ public static void T(object x)
compilation.VerifyDiagnostics(
// (11,18): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead.
// if (x is Nullable<int> y) Console.WriteLine($"expression {x} is Nullable<int> y");
Diagnostic(ErrorCode.ERR_PatternNullableType, "Nullable<int>").WithArguments("int?", "int").WithLocation(11, 18)
Diagnostic(ErrorCode.ERR_PatternNullableType, "Nullable<int>").WithArguments("int").WithLocation(11, 18)
);
}
......@@ -219,7 +219,7 @@ public static void Main()
Diagnostic(ErrorCode.ERR_BadPatternExpression, "null").WithArguments("<null>").WithLocation(10, 13),
// (11,18): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead.
// if (s is NullableInt x) { } // error: cannot use nullable type
Diagnostic(ErrorCode.ERR_PatternNullableType, "NullableInt").WithArguments("int?", "int").WithLocation(11, 18),
Diagnostic(ErrorCode.ERR_PatternNullableType, "NullableInt").WithArguments("int").WithLocation(11, 18),
// (12,18): error CS8121: An expression of type 'string' cannot be handled by a pattern of type 'long'.
// if (s is long l) { } // error: cannot convert string to long
Diagnostic(ErrorCode.ERR_PatternWrongType, "long").WithArguments("string", "long").WithLocation(12, 18),
......
......@@ -2573,6 +2573,65 @@ public void M(string s)
);
}
[Fact]
public void IsNullableReferenceType_01()
{
var source =
@"#nullable enable
public class C {
public void M1(object o) {
var t = o is string? { };
}
public void M2(object o) {
var t = o is (string? { });
}
public void M3(object o) {
var t = o is string?;
}
public void M4(object o) {
var t = o is string? _;
}
public void M5(object o) {
var t = o is (string? _);
}
}";
CreateCompilation(source, parseOptions: TestOptions.RegularWithPatternCombinators).VerifyDiagnostics(
// (4,22): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead.
// var t = o is string? { };
Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(4, 22),
// (7,22): error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'object', with 2 out parameters and a void return type.
// var t = o is (string? { });
Diagnostic(ErrorCode.ERR_MissingDeconstruct, "(string? { })").WithArguments("object", "2").WithLocation(7, 22),
// (7,29): error CS1003: Syntax error, ',' expected
// var t = o is (string? { });
Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments(",", "?").WithLocation(7, 29),
// (7,31): error CS1003: Syntax error, ',' expected
// var t = o is (string? { });
Diagnostic(ErrorCode.ERR_SyntaxError, "{").WithArguments(",", "{").WithLocation(7, 31),
// (10,22): error CS8650: It is not legal to use nullable reference type 'string?' in an is-type expression; use the underlying type 'string' instead.
// var t = o is string?;
Diagnostic(ErrorCode.ERR_IsNullableType, "string?").WithArguments("string").WithLocation(10, 22),
// (13,30): error CS0103: The name '_' does not exist in the current context
// var t = o is string? _;
Diagnostic(ErrorCode.ERR_NameNotInContext, "_").WithArguments("_").WithLocation(13, 30),
// (13,31): error CS1003: Syntax error, ':' expected
// var t = o is string? _;
Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(":", ";").WithLocation(13, 31),
// (13,31): error CS1525: Invalid expression term ';'
// var t = o is string? _;
Diagnostic(ErrorCode.ERR_InvalidExprTerm, ";").WithArguments(";").WithLocation(13, 31),
// (16,22): error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'object', with 2 out parameters and a void return type.
// var t = o is (string? _);
Diagnostic(ErrorCode.ERR_MissingDeconstruct, "(string? _)").WithArguments("object", "2").WithLocation(16, 22),
// (16,29): error CS1003: Syntax error, ',' expected
// var t = o is (string? _);
Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments(",", "?").WithLocation(16, 29),
// (16,31): error CS1003: Syntax error, ',' expected
// var t = o is (string? _);
Diagnostic(ErrorCode.ERR_SyntaxError, "_").WithArguments(",", "").WithLocation(16, 31)
);
}
[Fact]
public void IsAlwaysPatternKinds()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册