AI22-0044-1

!standard 4.3.1(17/5)                                    22-06-23  AI22-0044-1/02

!class binding interpretation 22-06-15

!status Corrigendum 1-2022 22-06-23

!status WG9 Approved 22-10-18

!status ARG Approved 14-0-1  22-06-23

!status work item 22-06-15

!status received 22-03-28

!priority Low

!difficulty Easy

!qualifier Omission

!subject Aggregate discriminants that do not satisfy predicates

!summary

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

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

!issue

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 and satisfies any predicates. 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.)

!recommendation

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

!wording

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.

!discussion

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

!example

(See issue.)

!corrigendum 4.3.1(17/5)

@drepl

For a @fa{record_aggregate} or @fa{extension_aggregate}, if a

@fa{variant_part} @i{P} is nested within a @fa{variant} @i{V} that is not

selected by the discriminant value governing the @fa{variant_part} enclosing

@i{V}, then there is no restriction on the discriminant governing @i{P}.

Otherwise, the value of the discriminant that governs @i{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 shall be

exactly one @fa{discrete_choice_list} of @i{P} that covers each value that

belongs to the nominal subtype and satisfies the predicates of the subtype,

and there shall be at least one such value.

@dby

For a @fa{record_aggregate} or @fa{extension_aggregate}, if a

@fa{variant_part} @i{P} is nested within a @fa{variant} @i{V} that is not

selected by the discriminant value governing the @fa{variant_part} enclosing

@i{V}, then there is no restriction on the discriminant governing @i{P}.

Otherwise, the value of the discriminant that governs @i{P} shall be given by

a static expression, or by a nonstatic expression having a constrained static

nominal subtype. There shall be

exactly one @fa{discrete_choice_list} of @i{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.

!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.

!appendix