Skip to content

Commit d10419e

Browse files
antonsyndclaude
andcommitted
fix(codegen): version exception variable names in nested try/except
Exception variables in catch clauses now use _variableVersions tracking to avoid CS0136 when nested try/except blocks use the same `as` name. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2e548af commit d10419e

3 files changed

Lines changed: 51 additions & 3 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
caught: outer
2+
caught: inner
3+
done
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
def main():
2+
try:
3+
raise ValueError("outer")
4+
except ValueError as e:
5+
outer_msg: str = "caught: outer"
6+
print(outer_msg)
7+
try:
8+
raise TypeError("inner")
9+
except TypeError as e:
10+
inner_msg: str = "caught: inner"
11+
print(inner_msg)
12+
print("done")

src/Sharpy.Compiler/CodeGen/RoslynEmitter.Statements.cs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,26 +1801,59 @@ private List<CatchClauseSyntax> GenerateCatchClauses(ImmutableArray<ExceptHandle
18011801
{
18021802
return handlers.Select(handler =>
18031803
{
1804-
var catchBlock = Block(handler.Body.SelectMany(GenerateBodyStatements));
1805-
18061804
if (handler.ExceptionType != null)
18071805
{
18081806
var exceptionType = _typeMapper.MapType(handler.ExceptionType);
18091807

18101808
if (handler.Name != null)
18111809
{
1812-
var exceptionVar = NameMangler.ToCamelCase(handler.Name);
1810+
var baseName = NameMangler.ToCamelCase(handler.Name);
1811+
1812+
// Track exception variable in _variableVersions so nested
1813+
// catch clauses with the same name get versioned (e, e_1, ...)
1814+
// to avoid CS0136 in generated C#.
1815+
var hadPrevious = _variableVersions.TryGetValue(baseName, out var previousVersion);
1816+
if (hadPrevious)
1817+
{
1818+
var newVersion = previousVersion + 1;
1819+
_variableVersions[baseName] = newVersion;
1820+
}
1821+
else
1822+
{
1823+
_variableVersions[baseName] = 0;
1824+
}
1825+
1826+
var exceptionVar = hadPrevious
1827+
? $"{baseName}_{_variableVersions[baseName]}"
1828+
: baseName;
1829+
1830+
_sourceVariableNames.Add(baseName);
1831+
1832+
var catchBlock = Block(handler.Body.SelectMany(GenerateBodyStatements));
18131833
var declaration = CatchDeclaration(exceptionType, Identifier(exceptionVar));
1834+
1835+
// Restore previous version state after generating the catch body
1836+
if (hadPrevious)
1837+
{
1838+
_variableVersions[baseName] = previousVersion;
1839+
}
1840+
else
1841+
{
1842+
_variableVersions.Remove(baseName);
1843+
}
1844+
18141845
return CatchClause(declaration, null, catchBlock);
18151846
}
18161847
else
18171848
{
1849+
var catchBlock = Block(handler.Body.SelectMany(GenerateBodyStatements));
18181850
var declaration = CatchDeclaration(exceptionType);
18191851
return CatchClause(declaration, null, catchBlock);
18201852
}
18211853
}
18221854
else
18231855
{
1856+
var catchBlock = Block(handler.Body.SelectMany(GenerateBodyStatements));
18241857
return CatchClause()
18251858
.WithBlock(catchBlock);
18261859
}

0 commit comments

Comments
 (0)