diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index 91c77b3134fb8f0d2bc456ff838ff19f7828976b..946483e93ee69e373a01c61cb9ba9ed851ff77f2 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -2069,6 +2069,12 @@ internal BoundExpression GenerateConversionForAssignment(TypeSymbol targetType, return; } + if (targetType.IsVoidType()) + { + Error(diagnostics, ErrorCode.ERR_NoImplicitConv, syntax, operand.Display, targetType); + return; + } + switch (operand.Kind) { case BoundKind.BadExpression: diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index e8ee09429c7f0b7348b748372bf3ab5d12526f54..d4c336caf4d7c5a57479920e6d85e424356ecbe3 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -1486,6 +1486,166 @@ public static void Main() Diagnostic(ErrorCode.ERR_NoImplicitConv, "m").WithArguments("bool", "int").WithLocation(6, 29)); } + [Fact, WorkItem(40405, "https://github.com/dotnet/roslyn/issues/40405")] + public void ThrowExpression_ImplicitVoidConversion_Return() + { + string text = @" +class C +{ + void M1() + { + return true ? throw null : M2(); + } + + void M2() { } +} +"; + CreateCompilation(text).VerifyDiagnostics( + // (6,23): error CS0029: Cannot implicitly convert type '' to 'void' + // return true ? throw null : M2(); + Diagnostic(ErrorCode.ERR_NoImplicitConv, "throw null").WithArguments("", "void").WithLocation(6, 23)); + } + + [Fact, WorkItem(40405, "https://github.com/dotnet/roslyn/issues/40405")] + public void ThrowExpression_ImplicitVoidConversion_Assignment() + { + string text = @" +class C +{ + void M1() + { + object obj = true ? throw null : M2(); + } + + void M2() { } +} +"; + CreateCompilation(text).VerifyDiagnostics( + // (6,29): error CS0029: Cannot implicitly convert type '' to 'void' + // object obj = true ? throw null : M2(); + Diagnostic(ErrorCode.ERR_NoImplicitConv, "throw null").WithArguments("", "void").WithLocation(6, 29)); + } + + [Fact, WorkItem(40405, "https://github.com/dotnet/roslyn/issues/40405")] + public void IntLiteral_ImplicitVoidConversion_Assignment() + { + string text = @" +class C +{ + void M1() + { + object obj = true ? 0 : M2(); + } + + void M2() { } +} +"; + CreateCompilation(text).VerifyDiagnostics( + // (6,22): error CS0173: Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and 'void' + // object obj = true ? 0 : M2(); + Diagnostic(ErrorCode.ERR_InvalidQM, "true ? 0 : M2()").WithArguments("int", "void").WithLocation(6, 22)); + } + + [Fact, WorkItem(40405, "https://github.com/dotnet/roslyn/issues/40405")] + public void VoidCall_ImplicitVoidConversion_Assignment() + { + string text = @" +class C +{ + void M1() + { + object obj = true ? M2() : M2(); + } + + void M2() { } +} +"; + CreateCompilation(text).VerifyDiagnostics( + // (6,22): error CS0029: Cannot implicitly convert type 'void' to 'object' + // object obj = true ? M2() : M2(); + Diagnostic(ErrorCode.ERR_NoImplicitConv, "true ? M2() : M2()").WithArguments("void", "object").WithLocation(6, 22)); + } + + [Fact, WorkItem(40405, "https://github.com/dotnet/roslyn/issues/40405")] + public void VoidCall_ImplicitVoidConversion_DiscardAssignment() + { + string text = @" +class C +{ + void M1() + { + _ = true ? M2() : M2(); + } + + void M2() { } +} +"; + CreateCompilation(text).VerifyDiagnostics( + // (6,9): error CS8209: A value of type 'void' may not be assigned. + // _ = true ? M2() : M2(); + Diagnostic(ErrorCode.ERR_VoidAssignment, "_").WithLocation(6, 9)); + } + + [Fact, WorkItem(40405, "https://github.com/dotnet/roslyn/issues/40405")] + public void VoidCall_Assignment() + { + string text = @" +class C +{ + void M1() + { + object obj = M2(); + } + + void M2() { } +} +"; + CreateCompilation(text).VerifyDiagnostics( + // (6,22): error CS0029: Cannot implicitly convert type 'void' to 'object' + // object obj = M2(); + Diagnostic(ErrorCode.ERR_NoImplicitConv, "M2()").WithArguments("void", "object").WithLocation(6, 22)); + } + + [Fact, WorkItem(40405, "https://github.com/dotnet/roslyn/issues/40405")] + public void VoidCall_DiscardAssignment() + { + string text = @" +class C +{ + void M1() + { + _ = M2(); + } + + void M2() { } +} +"; + CreateCompilation(text).VerifyDiagnostics( + // (6,9): error CS8209: A value of type 'void' may not be assigned. + // _ = M2(); + Diagnostic(ErrorCode.ERR_VoidAssignment, "_").WithLocation(6, 9)); + } + + [Fact, WorkItem(40405, "https://github.com/dotnet/roslyn/issues/40405")] + public void VoidCall_ImplicitVoidConversion_Return() + { + string text = @" +class C +{ + void M1() + { + return true ? M2() : M2(); + } + + void M2() { } +} +"; + CreateCompilation(text).VerifyDiagnostics( + // (6,9): error CS0127: Since 'C.M1()' returns void, a return keyword must not be followed by an object expression + // return true ? M2() : M2(); + Diagnostic(ErrorCode.ERR_RetNoObjectRequired, "return").WithArguments("C.M1()").WithLocation(6, 9)); + } + [Fact] public void CS0030ERR_NoExplicitConv() {