-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Report an error for dynamic evaluation of &&/|| when left operand is statically typed as an interface
#80962
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
Changes from 4 commits
fdd4ba3
571e0a5
68b6149
f75aade
3cf6ed6
ee63d62
fb27b79
39d733c
9c8745c
44ec8d4
92e9427
330d0f8
b7ae912
7c7b8ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3649,6 +3649,99 @@ dynamic M(dynamic d) | |
| ); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void DynamicBooleanExpression_InterfaceOperator_And() | ||
| { | ||
| const string source = @" | ||
| interface I1 | ||
| { | ||
| static bool operator true(I1 x) => false; | ||
| static bool operator false(I1 x) => false; | ||
| } | ||
|
|
||
| class C1 : I1 | ||
| { | ||
| public static C1 operator &(C1 x, C1 y) => x; | ||
| public static bool operator true(C1 x) => false; | ||
| public static bool operator false(C1 x) => false; | ||
| } | ||
|
|
||
| class Test | ||
| { | ||
| void M() | ||
| { | ||
| I1 x = new C1(); | ||
| dynamic y = new C1(); | ||
| _ = x && y; | ||
| } | ||
| }"; | ||
| CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyDiagnostics( | ||
| // (21,13): error CS7083: Expression must be implicitly convertible to Boolean or its type 'I1' must define operator 'false'. | ||
|
||
| Diagnostic(ErrorCode.ERR_InvalidDynamicCondition, "x").WithArguments("I1", "false") | ||
| ); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void DynamicBooleanExpression_InterfaceOperator_Or() | ||
| { | ||
| const string source = @" | ||
| interface I1 | ||
| { | ||
| static bool operator true(I1 x) => false; | ||
| static bool operator false(I1 x) => false; | ||
| } | ||
|
|
||
| class C1 : I1 | ||
| { | ||
| public static C1 operator |(C1 x, C1 y) => x; | ||
| public static bool operator true(C1 x) => false; | ||
| public static bool operator false(C1 x) => false; | ||
| } | ||
|
|
||
| class Test | ||
| { | ||
| void M() | ||
| { | ||
| I1 x = new C1(); | ||
| dynamic y = new C1(); | ||
| _ = x || y; | ||
| } | ||
| }"; | ||
| CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyDiagnostics( | ||
| // (21,13): error CS7083: Expression must be implicitly convertible to Boolean or its type 'I1' must define operator 'true'. | ||
| Diagnostic(ErrorCode.ERR_InvalidDynamicCondition, "x").WithArguments("I1", "true") | ||
| ); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void DynamicBooleanExpression_ClassWithoutOperator() | ||
| { | ||
| // Ensure the class case still works correctly (regression test) | ||
AlekseyTs marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const string source = @" | ||
| class C0 { } | ||
|
|
||
| class C1 : C0 | ||
| { | ||
| public static C1 operator &(C1 x, C1 y) => x; | ||
| public static bool operator true(C1 x) => false; | ||
| public static bool operator false(C1 x) => false; | ||
| } | ||
|
|
||
| class Test | ||
| { | ||
| void M() | ||
| { | ||
| C0 x = new C1(); | ||
| dynamic y = new C1(); | ||
| _ = x && y; | ||
| } | ||
| }"; | ||
| CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyDiagnostics( | ||
| // (17,13): error CS7083: Expression must be implicitly convertible to Boolean or its type 'C0' must define operator 'false'. | ||
| Diagnostic(ErrorCode.ERR_InvalidDynamicCondition, "x").WithArguments("C0", "false") | ||
| ); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void DynamicConstructorCall1() | ||
| { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot Please combine interface check with condition in
if (type.Kind != SymbolKind.NamedType)on line 1580 instead. #ClosedThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in commit 3cf6ed6. The interface check is now combined with the SymbolKind.NamedType check at line 1580, and the redundant check inside hasApplicableBooleanOperator has been removed.