dotnet/roslyn
View on GitHubVB: Strange widening-numeric conversion returned by ClassifyConversion
Open
#6,365 opened on Oct 27, 2015
Area-CompilersBugConcept-APIQuestionhelp wanted
Description
Consider the following VB program:
Module Program
Sub Main()
Dim b As Byte
b += 1
Console.WriteLine(b)
End Sub
End Module
I tried using the VB compiler API to classify the conversion between the right-side of the compound assignment statement (the numeric literal, 1) and the type of the left-side (System.Byte). My expectation is that this would classify as a narrowing-numeric conversion since 1 has the type, System.Int32. However, I was surprised to get back a widening-numeric conversion. Is this by design, or a bug? If it's by design, why?
Here's a C# interactive session I used to verify the result.
> #r "C:\Projects\Roslyn\Open\Binaries\Debug\Microsoft.CodeAnalysis.dll"
> #r "C:\Projects\Roslyn\Open\Binaries\Debug\Microsoft.CodeAnalysis.VisualBasic.dll"
> using Microsoft.CodeAnalysis;
> using Microsoft.CodeAnalysis.VisualBasic;
> using Microsoft.CodeAnalysis.VisualBasic.Syntax;
> var code = @"
. Module Program
.
. Sub Main()
. Dim b As Byte
. b += 1
.
. Console.WriteLine(b)
. End Sub
.
. End Module
. ";
> var tree = SyntaxFactory.ParseSyntaxTree(code);
> var compilation = VisualBasicCompilation.Create("Test")
. .AddSyntaxTrees(tree)
. .AddReferences(MetadataReference.CreateFromFile(@"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"));
> var semanticModel = compilation.GetSemanticModel(tree);
> var statements = tree.GetRoot().DescendantNodes().OfType<ExecutableStatementSyntax>().ToArray();
> var assignment = statements[1] as AssignmentStatementSyntax;
> assignment
AssignmentStatementSyntax(AssignmentStatementSyntax AddAssignmentStatement b += 1)
> var type = semanticModel.GetTypeInfo(assignment.Left).Type;
> type
PENamedTypeSymbolWithEmittedNamespaceName(NamedType System.Byte)
> var conversion = semanticModel.ClassifyConversion(assignment.Right, type);
> conversion
[WideningNumeric, InvolvesNarrowingFromNumericConstant]
>
Note that the conversion includes the internal InvolvesNarrowingFromNumericConstant flag as well, which seems a bit suspicious.