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

Compiler can't determine best common type for switch expression #8025

Open
gurustron opened this issue Jan 15, 2024 · 8 comments
Open

Compiler can't determine best common type for switch expression #8025

gurustron opened this issue Jan 15, 2024 · 8 comments

Comments

@gurustron
Copy link
Contributor

gurustron commented Jan 15, 2024

Probably my understanding of the spec in this part is incorrect, but according to switch expression feature spec:

The type of the switch_expression is the best common type (§11.6.3.15) of the expressions appearing to the right of the => tokens of the switch_expression_arms if such a type exists and the expression in every arm of the switch expression can be implicitly converted to that type.

And the natural function type has the following:

Function_types are used in a few specific contexts only:

  • implicit and explicit conversions
  • method type inference (§11.6.3) and best common type (§11.6.3.15)
  • var initializers

And:

Best common type (§11.6.3.15) is defined in terms of type inference so the type inference changes above apply to best common type as well.

With following sample which compiles:

var fs = new[] { (string s) => s.Length, (string s) => int.Parse(s) };

So for array construction compiler is able to determine the best common type.

Version Used:
.NET 8.0.101, C# 12

Steps to Reproduce:

Create a swtich expression with anonymous lambdas:

var func = (args.Length == 1) switch
{
    false => () => "Hello World",
    true => () => "Foo Bar"
};

A minimal repro, with source-code provided, is ideal. Repro @sharplab

Expected Behavior:

Compiles

Actual Behavior:

error CS8506: No best type was found for the switch expression.

@PoseidonEnergy
Copy link

PoseidonEnergy commented Jan 15, 2024

I would also like to highlight another discrepancy related to functions.

This does not compile:

var str = (() => "Hello World")(); // does not compile

However, this compiles:

var str = ((Func<string>)(() => "Hello World"))(); // compiles

@RikkiGibson
Copy link
Contributor

@cston for visibility. I think this is a subtle issue relating to lambda natural type.

@jaredpar
Copy link
Member

jaredpar commented Mar 8, 2024

@cston ping for comment on whether or not this is about lambda natural type

@cston
Copy link
Member

cston commented Mar 12, 2024

It looks like the best common type calculation for switch expressions currently ignores function types.

There is a similar issue with conditional expressions:

// error CS0173: Type of conditional expression cannot be determined
var func = (args.Length == 1) ? () => "Hello" : () => "World";

For switch expressions and conditional expressions, we could potentially use function types in the best common type calculation of the overall expression type.

@jaredpar
Copy link
Member

jaredpar commented Apr 1, 2024

Moving to csharplang as this is a design question vs. compiler impl.

@jaredpar jaredpar transferred this issue from dotnet/roslyn Apr 1, 2024
@CyrusNajmabadi
Copy link
Member

Definitely seems odd. I can't come up with a rational as to why array BCT works differently than switch or conditional BCT vis-a-vis function-types.

@HaloFour
Copy link
Contributor

HaloFour commented Apr 1, 2024

I would also like to highlight another discrepancy related to functions.

IIRC, the team decided against supporting IIFE in those scenarios:
https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-07-26.md#direct-invocation-of-lambdas

@PrinceSatish
Copy link

By explicitly casting the lambdas to Func, you provide the necessary type information for the compiler to determine the return type of the switch expression, and it will compile without errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants