postsharp / Metalama

Metalama is a Roslyn-based meta-programming framework. Use this repo to report bugs or ask questions.
164 stars 4 forks source link

Feature request: relax rules for LAMA0108 "cannot set the compile-time variable 'ii' here because is is part of a block whose execution depends on the run-time condition" #202

Closed WhitWaldo closed 9 months ago

WhitWaldo commented 11 months ago

I'm trying to solve a variable reference issue. Put simply, I have a loop inside a template that enumerates several compile-time values to write several run-time statements. As these are written to the method via meta.InsertStatement, they have no variable with which I can reference them elsewhere in the template (without resorting to another expression or statement builder). As such, I'm trying to use meta.CompileTime to provide a compile-time value I can append to this variable so they get different names. My code is similar to the following:

if ( //Runtime condition here)
{
  var ii = meta.CompileTime(0);

  foreach(var kv in myDict) //My dict is a compile-time dictionary
  {
    var sampleBuilder = new StatementBuilder();
    sampleBuilder.AppendVerbatim($"var abc{ii} = ");
    sampleBuilder.AppendLiteral(123);
    sampleBuilder.AppendVerbatim(";");
    meta.InsertStatement(sampleBuilder.ToStatement());
    var abc = ExpressionFactory.Parse($"abc{ii}").Value; //Give me a means of accessing the variable defined by the StatementBuilder

    ii += 1; //This is where I'm getting the error
  }
}

The error I'm seeing is:

LAMA0108: Cannot set the compile-time variable 'ii' here because is is part of a block whose execution depends on the run-time condition

And then it points to a run-time condition that's one step above where I originally instantiated it. It doesn't make sense to me that:

1) If it cannot increment in the run-time condition, that it would be able to be instantiated within it and 2) That it cannot increment within a compile-time loop

While I could move the runtime if statement within the loops, I'd rather not because it'll result it in simply repeating unnecessarily within each of the loops.

Thanks!

PostSharpBot commented 11 months ago

Hello @WhitWaldo, thank you for submitting this issue. We will try to get back to you as soon as possible. Note to the PostSharp team, this ticket is being tracked in our dashboard under ID TP-33611.

gfraiteur commented 11 months ago

We would need to refine the analysis to make this case possible.

Currently, we forbid updating any compile-time variable from a branch that depends on a run-time condition.

We should perform a smarter analysis because, in this case, the compile-time variable is itself defined under the run-time condition, and this is a legal situation because the compile-time variable is not observable outside of that condition. However, this is not a trivial analysis, and this improvement cannot be performed as a quick bug fix.

I would suggest finding a workaround in the meantime.

WhitWaldo commented 11 months ago

In the meantime, I moved the null check inside of run-time loop. It means that it repeats on every loop in the produced code, but at least it works for now.

gfraiteur commented 11 months ago

Reopening because we need to do something with it anyway.

prochan2 commented 9 months ago

Implemented in Metalama 2023.4.3-preview.