roslyn
roslyn copied to clipboard
False positive IDE0059 for variable captured by lambda in switch block
Version Used: VS 17.0 RC 2
Sample code:
Func<DnsMessage, ValueTask<DnsMessage>> queryMethod;
Console.Write("Choose DNS method: [T]CP / [U]DP / HTTP [G]ET / HTTP [P]OST: ");
switch (Console.ReadLine()![0])
{
case 'G' or 'g':
{
Console.WriteLine("Using HTTP GET.");
Uri? serverUri;
while (true)
{
Console.Write("Server url: ");
if (Uri.TryCreate(Console.ReadLine(), UriKind.Absolute, out serverUri)
&& serverUri.Scheme is "http" or "https")
break;
Console.WriteLine("Can't parse server url.");
}
var client = new HttpsDnsClient(serverUri); // 1
queryMethod = m => client.QueryAsync(m, HttpMethod.Get);
break;
}
case 'P' or 'p':
{
Console.WriteLine("Using HTTP POST.");
Uri? serverUri;
while (true)
{
Console.Write("Server url: ");
if (Uri.TryCreate(Console.ReadLine(), UriKind.Absolute, out serverUri)
&& serverUri.Scheme is "http" or "https")
break;
Console.WriteLine("Can't parse server url.");
}
var client = new HttpsDnsClient(serverUri); // 2
queryMethod = m => client.QueryAsync(m, HttpMethod.Post);
break;
}
case 'U' or 'u':
{
Console.WriteLine("Using UDP.");
IPAddress? serverAddress;
while (true)
{
Console.Write("DNS Server ip: ");
if (IPAddress.TryParse(Console.ReadLine(), out serverAddress))
break;
Console.WriteLine("Can't parse ip.");
}
var client = new UdpDnsClient(serverAddress); // 3
queryMethod = m => client.QueryAsync(m);
break;
}
default:
{
Console.WriteLine("Using TCP.");
IPAddress? serverAddress;
while (true)
{
Console.Write("DNS Server ip: ");
if (IPAddress.TryParse(Console.ReadLine(), out serverAddress))
break;
Console.WriteLine("Can't parse ip.");
}
var client = new TcpDnsClient(serverAddress); // 4
queryMethod = m => client.QueryAsync(m);
break;
}
}
Expected Behavior: No IDE0059 reported.
Actual Behavior:
All the client
variables are reported to be unused.
Minimal repo:
using System;
class C
{
void M()
{
Action act = null;
{
var [|capture|] = new object();
act = () => capture.ToString();
}
act();
}
}
The error is caused by any kind of block between the declaration of act
and the assignment. It seems to be caused by an error in flow analysis:
The SymbolsWriteMap
contains
[({capture}, {Microsoft.CodeAnalysis.Operations.LocalReferenceOperation}), false]
If the block is removed it contains
[({capture}, {Microsoft.CodeAnalysis.Operations.LocalReferenceOperation}), true]
and IDE0059 is not reported.
Thanks for reporting and analyzing the possible root cause. I just faced this bug myself and went to see if it was already reported, so you saved me some time from opening a new issue :)
Just to mention my duplicate issue https://github.com/dotnet/roslyn/issues/64198 - the same thing happens with an if
statement.