未验证 提交 5d4831cb 编写于 作者: N Neal Gafter 提交者: GitHub

When a recursive pattern has no explicit type and acts on a nullable, (#27652)

ensure we test for null *and* convert to the underlying type.
Fixes #27321
上级 94725125
......@@ -401,14 +401,8 @@ private static void Assert(bool condition, string message = null)
ArrayBuilder<BoundPatternBinding> bindings)
{
Debug.Assert(input.Type.IsErrorType() || recursive.InputType.IsErrorType() || input.Type == recursive.InputType);
if (recursive.DeclaredType != null)
{
input = MakeConvertToType(input, recursive.Syntax, recursive.DeclaredType.Type, tests);
}
else
{
MakeCheckNotNull(input, recursive.Syntax, tests);
}
var inputType = recursive.DeclaredType?.Type ?? input.Type.StrippedType();
input = MakeConvertToType(input, recursive.Syntax, inputType, tests);
if (!recursive.Deconstruction.IsDefault)
{
......@@ -428,10 +422,10 @@ private static void Assert(bool condition, string message = null)
MakeTestsAndBindings(output, pattern, tests, bindings);
}
}
else if (input.Type.IsTupleType)
else if (inputType.IsTupleType)
{
ImmutableArray<FieldSymbol> elements = input.Type.TupleElements;
ImmutableArray<TypeSymbol> elementTypes = input.Type.TupleElementTypes;
ImmutableArray<FieldSymbol> elements = inputType.TupleElements;
ImmutableArray<TypeSymbol> elementTypes = inputType.TupleElementTypes;
int count = Math.Min(elementTypes.Length, recursive.Deconstruction.Length);
for (int i = 0; i < count; i++)
{
......
......@@ -1826,5 +1826,80 @@ .maxstack 2
IL_001e: ret
}");
}
[Fact]
public void DeconstructNullableTuple_01()
{
var source =
@"
class C {
static int i = 3;
static (int,int)? GetNullableTuple() => (i++, i++);
static void Main() {
if (GetNullableTuple() is (int x1, int y1) tupl1)
{
System.Console.WriteLine($""x = {x1}, y = {y1}"");
}
if (GetNullableTuple() is (int x2, int y2) _)
{
System.Console.WriteLine($""x = {x2}, y = {y2}"");
}
switch (GetNullableTuple())
{
case (int x3, int y3) s:
System.Console.WriteLine($""x = {x3}, y = {y3}"");
break;
}
}
}";
var compilation = CreateCompilation(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics();
var expectedOutput = @"x = 3, y = 4
x = 5, y = 6
x = 7, y = 8";
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
}
[Fact]
public void DeconstructNullable_01()
{
var source =
@"
class C {
static int i = 3;
static S? GetNullableTuple() => new S(i++, i++);
static void Main() {
if (GetNullableTuple() is (int x1, int y1) tupl1)
{
System.Console.WriteLine($""x = {x1}, y = {y1}"");
}
if (GetNullableTuple() is (int x2, int y2) _)
{
System.Console.WriteLine($""x = {x2}, y = {y2}"");
}
switch (GetNullableTuple())
{
case (int x3, int y3) s:
System.Console.WriteLine($""x = {x3}, y = {y3}"");
break;
}
}
}
struct S
{
int x, y;
public S(int X, int Y) => (this.x, this.y) = (X, Y);
public void Deconstruct(out int X, out int Y) => (X, Y) = (x, y);
}
";
var compilation = CreateCompilation(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics();
var expectedOutput = @"x = 3, y = 4
x = 5, y = 6
x = 7, y = 8";
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
}
}
}
......@@ -25,7 +25,6 @@ public static class TestOptions
public static readonly CSharpParseOptions ExperimentalParseOptions =
new CSharpParseOptions(kind: SourceCodeKind.Regular, documentationMode: DocumentationMode.None, languageVersion: LanguageVersion.Latest).WithFeatures(s_experimentalFeatures);
// PROTOTYPE(patterns2): Currently accepting recursive patterns in C# 7.3 until we have a language version 8.0 implemented.
public static readonly CSharpParseOptions RegularWithoutRecursivePatterns = Regular7_3;
public static readonly CSharpParseOptions RegularWithRecursivePatterns = Regular8;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册