Skip to content

Commit 077bddc

Browse files
authored
Convert non-generic enumerator values (#2757)
Fixes #2752 Copilot-Session: d27ee0ef-46db-423b-93dc-db64f8eae1ff
1 parent d62b152 commit 077bddc

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

src/Core/CodeAnalysis/Lowering/Lowerer.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,10 @@ private BoundStatement LowerCollectionRange(BoundForRangeStatement node, bool is
940940
// continues to destructure into `Current.Key` / `Current.Value`.
941941
if (node.KeyVariable == null)
942942
{
943-
statements.Add(new BoundVariableDeclaration(node.Syntax, node.ValueVariable, currentAccess));
943+
statements.Add(new BoundVariableDeclaration(
944+
node.Syntax,
945+
node.ValueVariable,
946+
ConvertEnumeratorCurrent(currentAccess, node.ValueVariable.Type)));
944947
}
945948
else
946949
{
@@ -986,7 +989,10 @@ private BoundStatement LowerCollectionRange(BoundForRangeStatement node, bool is
986989
statements.Add(new BoundVariableDeclaration(node.Syntax, node.KeyVariable, new BoundVariableExpression(node.Syntax, indexSymbol)));
987990
}
988991

989-
statements.Add(new BoundVariableDeclaration(node.Syntax, node.ValueVariable, currentAccess));
992+
statements.Add(new BoundVariableDeclaration(
993+
node.Syntax,
994+
node.ValueVariable,
995+
ConvertEnumeratorCurrent(currentAccess, node.ValueVariable.Type)));
990996
}
991997

992998
statements.Add(node.Body);
@@ -1055,6 +1061,13 @@ private BoundStatement LowerCollectionRange(BoundForRangeStatement node, bool is
10551061
return new BoundBlockStatement(node.Syntax, statements.ToImmutable());
10561062
}
10571063

1064+
private static BoundExpression ConvertEnumeratorCurrent(BoundExpression current, TypeSymbol elementType)
1065+
{
1066+
return current.Type == TypeSymbol.Object || current.Type?.ClrType.IsSameAs(typeof(object)) == true
1067+
? new BoundConversionExpression(current.Syntax, elementType, current)
1068+
: current;
1069+
}
1070+
10581071
private static BoundExpression TryBuildEnumeratorDisposeCall(LocalVariableSymbol enumeratorSymbol)
10591072
{
10601073
var clrType = enumeratorSymbol.Type?.ClrType;

test/Compiler.Tests/Emit/Issue1462ListEnumeratorEmitTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,28 @@ namespace GSharp.Compiler.Tests.Emit;
5050
/// </summary>
5151
public class Issue1462ListEnumeratorEmitTests
5252
{
53+
[Fact]
54+
public void NonGenericEnumeratorCurrent_IsConvertedToTheInferredElementType()
55+
{
56+
var source = """
57+
package Issue2752
58+
import System
59+
import System.Text.RegularExpressions
60+
61+
var count = 0
62+
for match in Regex.Matches("<input><span><input>", "<input>") {
63+
if match.Success {
64+
count = count + 1
65+
}
66+
}
67+
68+
Console.WriteLine(count)
69+
""";
70+
71+
var output = CompileAndRun(source);
72+
Assert.Equal("2\n", output);
73+
}
74+
5375
[Fact]
5476
public void EndToEnd_ForeachOverListOfSameCompilationTypes_VerifiesAndRuns()
5577
{

0 commit comments

Comments
 (0)