From 54bd2430cf65c0a9703a4a266aba45e088dff304 Mon Sep 17 00:00:00 2001 From: ike709 Date: Sun, 8 Dec 2024 21:48:02 -0600 Subject: [PATCH] Compile error when outputting to const vars in `for()` loops (#2124) Co-authored-by: ike709 Co-authored-by: wixoa --- .../Statements/For/reuse_decl_const.dm | 2 +- .../Tests/Statements/For/reuse_decl_const2.dm | 18 ++++++++++++++++++ DMCompiler/DM/Builders/DMProcBuilder.cs | 9 ++++++++- DMCompiler/DM/Expressions/LValue.cs | 1 + 4 files changed, 28 insertions(+), 2 deletions(-) rename Content.Tests/DMProject/{Broken Tests => Tests}/Statements/For/reuse_decl_const.dm (89%) create mode 100644 Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const2.dm diff --git a/Content.Tests/DMProject/Broken Tests/Statements/For/reuse_decl_const.dm b/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const.dm similarity index 89% rename from Content.Tests/DMProject/Broken Tests/Statements/For/reuse_decl_const.dm rename to Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const.dm index 4b404cb05c..2f39dc4f12 100644 --- a/Content.Tests/DMProject/Broken Tests/Statements/For/reuse_decl_const.dm +++ b/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const.dm @@ -1,4 +1,4 @@ -// COMPILE ERROR +// COMPILE ERROR OD0501 /datum var/const/idx = 0 diff --git a/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const2.dm b/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const2.dm new file mode 100644 index 0000000000..a8144a4359 --- /dev/null +++ b/Content.Tests/DMProject/Tests/Statements/For/reuse_decl_const2.dm @@ -0,0 +1,18 @@ +// COMPILE ERROR OD0501 + +/datum + var/const/idx = 0 + var/c = 0 + proc/do_loop() + for (idx in list(1,2,3)) + c += idx + +/proc/RunTest() + var/datum/d = new + d.do_loop() + + var/const/idx = 0 + var/c = 0 + for (idx in list(1,2,3)) + c += idx + diff --git a/DMCompiler/DM/Builders/DMProcBuilder.cs b/DMCompiler/DM/Builders/DMProcBuilder.cs index e4fcd52a2d..38f2c0d729 100644 --- a/DMCompiler/DM/Builders/DMProcBuilder.cs +++ b/DMCompiler/DM/Builders/DMProcBuilder.cs @@ -489,6 +489,10 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) { var outputVar = _exprBuilder.Create(outputExpr); + if (outputVar is Local { LocalVar: DMProc.LocalConstVariable } or Field { IsConst: true }) { + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); + } + var start = _exprBuilder.Create(exprRange.StartRange); var end = _exprBuilder.Create(exprRange.EndRange); var step = exprRange.Step != null @@ -520,7 +524,10 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) { if (outputVar is Local outputLocal) { outputLocal.LocalVar.ExplicitValueType = statementFor.DMTypes; - } + if(outputLocal.LocalVar is DMProc.LocalConstVariable) + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); + } else if (outputVar is Field { IsConst: true }) + compiler.Emit(WarningCode.WriteToConstant, outputExpr.Location, "Cannot change constant value"); ProcessStatementForList(list, outputVar, statementFor.DMTypes, statementFor.Body); break; diff --git a/DMCompiler/DM/Expressions/LValue.cs b/DMCompiler/DM/Expressions/LValue.cs index a32902f4f9..d5fd05f468 100644 --- a/DMCompiler/DM/Expressions/LValue.cs +++ b/DMCompiler/DM/Expressions/LValue.cs @@ -122,6 +122,7 @@ public override void EmitPushInitial(ExpressionContext ctx) { // Identifier of field internal sealed class Field(Location location, DMVariable variable, DMComplexValueType valType) : LValue(location, variable.Type) { + public bool IsConst { get; } = variable.IsConst; public override DMComplexValueType ValType => valType; public override void EmitPushInitial(ExpressionContext ctx) {