Hydrogene yields stale local values in switch expressions

Hi Marc et al,

I found what looks like a Hydrogene compiler issue involving a local declared first and assigned afterward. The local has the correct value when printed, but a C# switch expression appears to use its original default value instead.

Minimal repro:

using System;

int number;
number = 2;

var result = number switch
{
    0 => "Zero",
    1 => "One",
    2 => "Two",
    3 => "Three",
    _ => "Other",
};

writeLn($"number = {number}, result = {result}");

Expected:

number = 2, result = Two

Actual with Hydrogene 13.0.0.3141, in both Debug and Release:

number = 2, result = Zero

The equivalent code works when the variable is initialized as part of its declaration:

var number = 2;

A traditional switch/case statement also produces the expected result. I also ran the same minimal source under Roslyn in Debug and Release, where it produces the expected output.

I used GenAI to help organize the investigation and produce the attached Hydrogene-Stale-Local-Bug-Report.md. It includes the narrowing process, additional reduced repros, Debug/Release results, and the separate Roslyn control evidence. I reviewed the results and repros, but wanted to provide the fuller document in case it makes diagnosis easier.

Thanks!
Hydrogene-Stale-Local-Bug-Report.pdf (96.1 KB)

Logged as bugs://E27963.

I tested the equivalent in Oxygene and it passes the test. So, it has been determined that Oxygene is not stale :laughing:


namespace OxygeneStaleSwitch;

  begin
    var number1: Integer;
    if Integer.TryParse('1', out number1) then begin
      var description1 := case number1 of
        1: 'One';  // 'One'
        2: 'Two';
        else 'Other';
      end;
    
      writeLn(description1);
      
      //==================//
      var number2: Integer;

      if Integer.TryParse('2', out number2) then begin
        var copy := number2;

        var description2 := case number2 of
          2: 'Two';
          else 'Other';
        end;

        writeLn(copy);          // 2
        writeLn(description2);  // 'Two'
  end;

end.

Yeah, this is C#-only, all platform. already fixed internally, awaiting final test & merge approval. Sorry for neglecting to provide an updated status.