Visibility of aspect changes after freeze point

Hi, I got my first meeting with the dreaded freezing point issues. I’m pretty sure reading the rm won’t help a bit, but you must know the solution. With the following:

private with Ada.Streams;
package Root_Event.Engine is
  type Engine_Event is new Event with private;
  function Create return Engine_Event;
  procedure Simulate(E: in Engine_Event);
  type Main_Engine_Event is new Engine_Event with private;
  function Create return Main_Engine_Event;
  type Aux_Engine_Event is new Engine_Event with private;
  function Create return Aux_Engine_Event;
  procedure Simulate(E: in Aux_Engine_Event);
private
  use Ada.Streams;
  type Engine_Event is new Event with 
    record
      Fuel, Oxygen: Natural;
    end record with Write => E_E_Write, Read => E_E_Read;
  type Main_Engine_Event is new Engine_Event with null record;
  procedure E_E_Read
    (Stream : not null access Root_Stream_Type'Class;
    Item : out Engine_Event);
  procedure E_E_Write
    (Stream : not null access Root_Stream_Type'Class;
    Item : in Engine_Event);
  type Aux_Engine_ID is (Left, Right);
  type Aux_Engine_Event is new Engine_Event with 
  record
      Side: Aux_Engine_ID;
  end record with Write => A_E_E_Write, Read => A_E_E_Read;
  procedure A_E_E_Read
    (Stream : not null access Root_Stream_Type'Class;
    Item : out Aux_Engine_Event);
  procedure A_E_E_Write
    (Stream : not null access Root_Stream_Type'Class;
    Item : in Aux_Engine_Event);
end Root_Event.Engine;

I get

root_event-engine.ads:24:21: error: visibility of aspect for “Engine_Event” changes after freeze point
root_event-engine.ads:24:30: error: “E_E_Write” is undefined
root_event-engine.ads:24:41: error: visibility of aspect for “Engine_Event” changes after freeze point
root_event-engine.ads:24:49: error: “E_E_Read” is undefined
root_event-engine.ads:28:13: error: this primitive operation is declared too late
root_event-engine.ads:32:13: error: this primitive operation is declared too late

Before I have had no problem when a single type defined in a package, but I hope there are other solutions than multiplying the number of files.

private with Ada.Streams;
package Root_Event is
  type Event is abstract tagged private;
  function  Create return Event is abstract;
  procedure Simulate(E: in Event) is abstract;
  function "<"(Left, Right: Event'Class) return Boolean;
private
  use Ada.Streams;
  type Simulation_Time is range 0..10_000;
  for Simulation_Time'Stream_Size use 16;
  type Event is abstract tagged
    record
      Time: Simulation_Time;
    end record with Read => E_Read, Write => E_Write;
  procedure E_Read
    (Stream : not null access Root_Stream_Type'Class;
    Item : out Event);  
  procedure E_Write
    (Stream : not null access Root_Stream_Type'Class;
    Item : in Event);
end Root_Event;

You try to extend the base type before you add more functions to it, which will violate freezing rules. Once you extend it, it freezes:

type Engine_Event is new Event with 
    record
      Fuel, Oxygen: Natural;
    end record with Write => E_E_Write, Read => E_E_Read;
  type Main_Engine_Event is new Engine_Event with null record; -- HERE:  you freeze Engine_Event
  procedure E_E_Read
    (Stream : not null access Root_Stream_Type'Class;
    Item : out Engine_Event);
  procedure E_E_Write
    (Stream : not null access Root_Stream_Type'Class;
    Item : in Engine_Event);

Try moving that line down further past all things related to Engine_Event

The example you provided was not complete so I couldn’t verify if that is the only issue or not, but freezing a type means you can’t add primitive operations to it (like E_Read and E_Write)

Thank you, pretty obvious but I overlooked it.