提交 cd3fb953 编写于 作者: N Neal Gafter

Test for the diagnostic matching an expression to a nullable type in a pattern.

Implementation and test for pattern matching to an unconstrained type parameter.
上级 5a8bbf52
......@@ -106,6 +106,9 @@ BoundExpression DeclPattern(CSharpSyntaxNode syntax, BoundExpression input, Loca
}
else if (type.IsNullableType())
{
// This is a semantic error in the binder, so we should not get here.
// Not sure what the semantics should be, as (null is Nullable<int>) is false.
// bool Is<T>(object e, out T? t) where T : struct
// {
// t = e as T?;
......@@ -139,7 +142,10 @@ BoundExpression DeclPattern(CSharpSyntaxNode syntax, BoundExpression input, Loca
// if (s) o = (T)i;
// return s;
// }
throw new NotImplementedException();
return _factory.Conditional(_factory.Is(input, type),
_factory.Sequence(_factory.AssignmentExpression(_factory.Local(target), _factory.Convert(type, input)), _factory.Literal(true)),
_factory.Literal(false),
_factory.SpecialType(SpecialType.System_Boolean));
}
}
}
......
......@@ -481,6 +481,13 @@ public BoundAsOperator As(BoundExpression operand, TypeSymbol type)
return new BoundAsOperator(this.Syntax, operand, Type(type), Conversion.ExplicitReference, type) { WasCompilerGenerated = true };
}
public BoundIsOperator Is(BoundExpression operand, TypeSymbol type)
{
HashSet<DiagnosticInfo> discarded = null;
Conversion c = Compilation.Conversions.ClassifyConversionFromExpression(operand, type, ref discarded);
return new BoundIsOperator(this.Syntax, operand, Type(type), c, SpecialType(Microsoft.CodeAnalysis.SpecialType.System_Boolean)) { WasCompilerGenerated = true };
}
public BoundBinaryOperator LogicalAnd(BoundExpression left, BoundExpression right)
{
return Binary(BinaryOperatorKind.LogicalBoolAnd, SpecialType(Microsoft.CodeAnalysis.SpecialType.System_Boolean), left, right);
......
......@@ -58,6 +58,72 @@ 4. 12
var comp = CompileAndVerify(compilation, expectedOutput: expectedOutput);
}
[Fact]
public void NullablePatternTest()
{
var source =
@"using System;
public class X
{
public static void Main()
{
T(null);
T(1);
}
public static void T(object x)
{
if (x is Nullable<int> y) Console.WriteLine($""expression {x} is Nullable<int> y"");
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
compilation.VerifyDiagnostics(
// (11,18): error CS8105: 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)
);
}
[Fact]
public void UnconstrainedPatternTest()
{
var source =
@"using System;
public class X
{
public static void Main()
{
Test<string>(1);
Test<int>(""foo"");
Test<int>(1);
Test<int>(1.2);
Test<double>(1.2);
Test<int?>(1);
Test<int?>(null);
Test<string>(null);
}
public static void Test<T>(object x)
{
if (x is T y)
Console.WriteLine($""expression {x} is {typeof(T).Name} {y}"");
else
Console.WriteLine($""expression {x} is not {typeof(T).Name}"");
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: patternParseOptions);
compilation.VerifyDiagnostics(
);
var expectedOutput =
@"expression 1 is not String
expression foo is not Int32
expression 1 is Int32 1
expression 1.2 is not Int32
expression 1.2 is Double 1.2
expression 1 is Nullable`1 1
expression is not Nullable`1
expression is not String";
var comp = CompileAndVerify(compilation, expectedOutput: expectedOutput);
}
[Fact]
public void PropertyPatternTest()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册