roslyn: Missing compiler generated switch expression arm in/from ISwitchExpressionOperation

Version Used: 16.10.0 Preview 1.0

Steps to Reproduce: Compile:

using System;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Operations;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

var tree = ParseSyntaxTree(@"
	
	var x = X.A;
	
	var xText = x switch {
		X.A => 1,
		X.B => 2,
	};
						   
	public enum X {
		A, B
	}
");


var refApis = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic).Select(a => MetadataReference.CreateFromFile(a.Location));
var com = CSharpCompilation.Create("something", new []{ tree }, refApis );
var model = com.GetSemanticModel(tree);

var switchExpr = tree.GetRoot().DescendantNodes().OfType<SwitchExpressionSyntax>().First();

var switchExprOp = (ISwitchExpressionOperation)model.GetOperation(switchExpr);

//---only two arms are returned:
Console.WriteLine($"expected: {3}");
Console.WriteLine($"actual {switchExprOp.Arms.Count()}");

//SwitchExpressionArm warning is issued
Console.WriteLine();
Console.WriteLine("Diagnostics");
Console.WriteLine("---------");
foreach(var d in com.GetDiagnostics())
{
  Console.WriteLine(d);	
}

Expected Behavior: All arms (in this case 3), including the generated “SwitchExpressionException” - arm should be returned from ISwitchExpressionOperation

And if you look at the lowered code, you can see that such an arm is created (link)

Actual Behavior: Only the user defined arms are returned.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 15 (15 by maintainers)

Most upvoted comments

I wouldn’t be opposed to a flag on the switch expression operation to indicate whether it was exhaustive, as that’s a piece of semantic info.

Sounds reasonable to me.

Control-Flow-Graph.