Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure initial binding always binds to natural type #48205

Merged
merged 5 commits into from
Oct 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3165,6 +3165,10 @@ private BoundExpression BindArrayDimension(ExpressionSyntax dimension, Diagnosti
hasErrors = true;
}
}
else
{
size = BindToTypeForErrorRecovery(size);
}

return size;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2354,7 +2354,7 @@ internal BoundExpression BindBooleanExpression(ExpressionSyntax node, Diagnostic
// The expression could not be bound. Insert a fake conversion
// around it to bool and keep on going.
// NOTE: no user-defined conversion candidates.
return BoundConversion.Synthesized(node, expr, Conversion.NoConversion, false, explicitCastInCode: false, conversionGroupOpt: null, ConstantValue.NotAvailable, boolean, hasErrors: true);
return BoundConversion.Synthesized(node, BindToTypeForErrorRecovery(expr), Conversion.NoConversion, false, explicitCastInCode: false, conversionGroupOpt: null, ConstantValue.NotAvailable, boolean, hasErrors: true);
}

// Oddly enough, "if(dyn)" is bound not as a dynamic conversion to bool, but as a dynamic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,132 @@ public void M1()
VerifyOperationTreeAndDiagnosticsForTest<ImplicitObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics, parseOptions: ImplicitObjectCreationOptions);
}

[CompilerTrait(CompilerFeature.IOperation)]
[Fact, WorkItem(1198816, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1198816/")]
public void ImplicitObjectCreationUnconverted_ArrayIndex()
{
var comp = CreateCompilation("_ = new int[/*<bind>*/new(bad)/*</bind>*/];", options: TestOptions.ReleaseExe);

var expectedDiagnostics = new DiagnosticDescription[] {
// (1,27): error CS0103: The name 'bad' does not exist in the current context
// _ = new int[/*<bind>*/new(bad)/*</bind>*/];
Diagnostic(ErrorCode.ERR_NameNotInContext, "bad").WithArguments("bad").WithLocation(1, 27)
};

VerifyOperationTreeAndDiagnosticsForTest<ImplicitObjectCreationExpressionSyntax>(comp, @"
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'new(bad)')
Children(1):
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'bad')
Children(0)
", expectedDiagnostics);
}

[CompilerTrait(CompilerFeature.IOperation)]
[Fact, WorkItem(1198816, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1198816/")]
public void ImplicitObjectCreationUnconverted_IfCondition()
{
var comp = CreateCompilation(@"
if (/*<bind>*/new(bad)/*</bind>*/) {}
", options: TestOptions.UnsafeReleaseExe);

var expectedDiagnostics = new DiagnosticDescription[] {
// (2,19): error CS0103: The name 'bad' does not exist in the current context
// if (/*<bind>*/new(bad)/*</bind>*/) {}
Diagnostic(ErrorCode.ERR_NameNotInContext, "bad").WithArguments("bad").WithLocation(2, 19)
};

VerifyOperationTreeAndDiagnosticsForTest<ImplicitObjectCreationExpressionSyntax>(comp, @"
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'new(bad)')
Children(1):
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'bad')
Children(0)
", expectedDiagnostics);
}

[CompilerTrait(CompilerFeature.IOperation)]
[Fact, WorkItem(1198816, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1198816/")]
public void ImplicitObjectCreationUnconverted_ConditionalOperator()
{
var source =
@"class Program
{
static void Main()
{
_ = /*<bind>*/new(bad)/*</bind>*/ ? null : new object();
}
}";
var comp = CreateCompilation(source);

var expectedDiagnostics = new DiagnosticDescription[] {
// (5,27): error CS0103: The name 'bad' does not exist in the current context
// _ = /*<bind>*/new(bad)/*</bind>*/ ? null : new object();
Diagnostic(ErrorCode.ERR_NameNotInContext, "bad").WithArguments("bad").WithLocation(5, 27)
};

VerifyOperationTreeAndDiagnosticsForTest<ImplicitObjectCreationExpressionSyntax>(comp, @"
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'new(bad)')
Children(1):
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'bad')
Children(0)
", expectedDiagnostics);
}

[CompilerTrait(CompilerFeature.IOperation)]
[Fact, WorkItem(1198816, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1198816/")]
public void ImplicitObjectCreationUnconverted_ConditionalOperator_Nested1()
{
var source =
@"class Program
{
static void Main()
{
_ = (/*<bind>*/new(bad)/*</bind>*/, null) ? null : new object();
}
}";
var comp = CreateCompilation(source);

var expectedDiagnostics = new DiagnosticDescription[] {
// (5,28): error CS0103: The name 'bad' does not exist in the current context
// _ = (/*<bind>*/new(bad)/*</bind>*/, null) ? null : new object();
Diagnostic(ErrorCode.ERR_NameNotInContext, "bad").WithArguments("bad").WithLocation(5, 28)
};

VerifyOperationTreeAndDiagnosticsForTest<ImplicitObjectCreationExpressionSyntax>(comp, @"
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'new(bad)')
Children(1):
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'bad')
Children(0)
", expectedDiagnostics);
}

[CompilerTrait(CompilerFeature.IOperation)]
[Fact, WorkItem(1198816, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1198816/")]
public void ImplicitObjectCreationUnconverted_ConditionalOperator_Nested2()
{
var source =
@"class Program
{
static void Main(int i)
{
_ = i switch { 1 => /*<bind>*/new(bad)/*</bind>*/, _ => null } ? null : new object();
}
}";
var comp = CreateCompilation(source);

var expectedDiagnostics = new DiagnosticDescription[] {
// (5,43): error CS0103: The name 'bad' does not exist in the current context
// _ = i switch { 1 => /*<bind>*/new(bad)/*</bind>*/, _ => null } ? null : new object();
Diagnostic(ErrorCode.ERR_NameNotInContext, "bad").WithArguments("bad").WithLocation(5, 43)
};

VerifyOperationTreeAndDiagnosticsForTest<ImplicitObjectCreationExpressionSyntax>(comp, @"
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'new(bad)')
Children(1):
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'bad')
Children(0)
", expectedDiagnostics);
}

[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void ImplicitObjectCreationWithDynamicMemberInitializer_01()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1499,5 +1499,24 @@ public TestClass Self()

CompileAndVerify(compilation, expectedOutput: "---");
}

[Fact, WorkItem(1198816, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1198816/")]
public void DefiniteAssignment_UnconvertedConditionalOperator()
{
var source =
@"class Program
{
static void Main()
{
_ = new(bad) ? null : new object();
}
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (5,17): error CS0103: The name 'bad' does not exist in the current context
// _ = new(bad) ? null : new object();
Diagnostic(ErrorCode.ERR_NameNotInContext, "bad").WithArguments("bad").WithLocation(5, 17)
);
}
333fred marked this conversation as resolved.
Show resolved Hide resolved
}
}