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) {