!standard 4.3.1(17/5)                                    22-06-15  AI22-044-1/01

!class binding interpretation 22-06-15

!status work item 22-06-15

!status received 22-03-28

!priority Low

!difficulty Easy

!qualifier Omission

!subject Aggregate discriminants that do not belong to their subtype


In an aggregate, a static value given for a discriminant that governs one

or more variant parts needs to satisfy the subtype of the discriminant.


In an aggregate, the value of a discriminant that governs one or more variant parts has to either be a static expression or an expression with a constrained static nominal subtype. In the latter case, there is a check that the value belongs to the subtype. However, there is no similar check for a static expression.

This matters when the subtype of the discriminant has a (static) predicate Consider:

subtype Account_Number_Type is Integer
   with Static_Predicate => Account_Number_Type in 1 .. 9_999;

type Account_Type (Account_Number : Account_Number_Type := 1) is record
  case Account_Number is
     when         1 .. 4_999 =>
                Savings_Rate : Float;
     when 5_000 .. 9_999 =>
              Loan_Rate : Float;
   end case;
end record;

Obj : Account_Type := Account_Type'(Account_Number => 0); -- Legal? (No.)


Here, the discriminant value doesn't select any variant, so we don't know which components are needed.

Since '0' is an integer literal, it is a static expression. The expected subtype does not matter for this purpose (and this was confirmed by AI12-0393-1). So 4.3.1(17/5) is satisfied. Thus it appears that this aggregate is legal, assuming all of the needed components are included. How do we determine the needed components for this aggregate? (It is illegal.)


Require the value to belong to the subtype of the discriminant for a static expression that governs a variant.


Modify 4.3.1(17/5):

For a record_aggregate or extension_aggregate, if a variant_part P is nested within a variant V that is not selected by the discriminant value governing the variant_part enclosing V, then there is no restriction on the discriminant governing P. Otherwise, the value of the discriminant that governs P shall be given by a static expression, or by a nonstatic expression having a constrained static nominal subtype. [In this latter case of a nonstatic expression, there]{There} shall be exactly one discrete_choice_list of P that covers {every possible value of the expression, which in the case of a nonstatic expression includes} each value that belongs to the nominal subtype and satisfies the predicates of the subtype, and there shall be at least one such value.


An alternative approach would be to consider the aggregate to have an implicit empty others variant. But that would work differently than the non-static case and would be different than occurs anywhere else.

We also could have used a runtime check (similarly to the non-static case) rather than making the aggregate illegal. But we generally make things illegal rather than having them always raising an exception (as there is always a small risk that testing would miss the aggregate and a fielded system would be raising an unexpected exception).


(See issue.)

!ACATS test

An ACATS B-Test should be constructed to check that this new rule is enforced, both for record aggregates and for extension aggregates..