-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Open
Labels
Milestone
Description
[CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)]
[Fact]
public void ObjectCreationFlow_75_CollectionInitializerError()
{
string source = @"
public class C
{
public static void Main()
/*<bind>*/{
int d = 1;
var c = new C() { [d] = {2} };
}/*</bind>*/
C2 _test1 = new C2();
C2 this[int x]
{
get => _test1;
}
}
class C2
{
}
";
var expectedDiagnostics = new[] {
// (7,33): error CS1922: Cannot initialize type 'C2' with a collection initializer because it does not implement 'System.Collections.IEnumerable'
// var c = new C() { [d] = {2} };
Diagnostic(ErrorCode.ERR_CollectionInitRequiresIEnumerable, "{2}").WithArguments("C2").WithLocation(7, 33)
};
string expectedFlowGraph = @"
";
VerifyFlowGraphAndDiagnosticsForTest<BlockSyntax>(source, expectedFlowGraph, expectedDiagnostics);
}
Observed:
Capture [1] is not used in region [R3] before leaving it after block [B3]
Block[B0] - Entry
Statements (0)
Next (Regular) Block[B1]
Entering: {R1}
.locals {R1}
{
Locals: [System.Int32 d] [C c]
Block[B1] - Block
Predecessors: [B0]
Statements (1)
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: 'd = 1')
Left:
ILocalReferenceOperation: d (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'd = 1')
Right:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
Next (Regular) Block[B2]
Entering: {R2}
.locals {R2}
{
CaptureIds: [0]
Block[B2] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsInvalid, IsImplicit) (Syntax: 'new C() { [d] = {2} }')
Value:
IObjectCreationOperation (Constructor: C..ctor()) (OperationKind.ObjectCreation, Type: C, IsInvalid) (Syntax: 'new C() { [d] = {2} }')
Arguments(0)
Initializer:
null
Next (Regular) Block[B3]
Entering: {R3}
.locals {R3}
{
CaptureIds: [1]
Block[B3] - Block
Predecessors: [B2]
Statements (2)
IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'd')
Value:
ILocalReferenceOperation: d (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'd')
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid, IsImplicit) (Syntax: '2')
Children(1):
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2, IsInvalid) (Syntax: '2')
Next (Regular) Block[B4]
Leaving: {R3}
}
Block[B4] - Block
Predecessors: [B3]
Statements (1)
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: C, IsInvalid, IsImplicit) (Syntax: 'c = new C() ... [d] = {2} }')
Left:
ILocalReferenceOperation: c (IsDeclaration: True) (OperationKind.LocalReference, Type: C, IsInvalid, IsImplicit) (Syntax: 'c = new C() ... [d] = {2} }')
Right:
IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: C, IsInvalid, IsImplicit) (Syntax: 'new C() { [d] = {2} }')
Next (Regular) Block[B5]
Leaving: {R2} {R1}
}
}
Block[B5] - Exit
Predecessors: [B4]
Statements (0)
Expected: True
Actual: False
Either we should relax the validation to specifically target the scenario, or we can slightly adjust the graph creation so that it included the capture as a child of an IInvalidOperation representing erroneous element add. The second is probably going to be easier to implement.
Reactions are currently unavailable