Ada Reference Manual (Ada 2022) — Legal Information

# 4.3.2 Extension Aggregates

1
An extension_aggregate specifies a value for a type that is a record extension by specifying a value or subtype for an ancestor of the type, followed by associations for any components not determined by the ancestor_part.

#### Syntax

2
extension_aggregate ::=
(ancestor_part with record_component_association_list)
3
ancestor_part ::= expression | subtype_mark

#### Name Resolution Rules

4/2
The expected type for an extension_aggregate shall be a single type that is a record extension. If the ancestor_part is an expression, it is expected to be of any tagged type.

#### Legality Rules

5/3
If the ancestor_part is a subtype_mark, it shall denote a specific tagged subtype. If the ancestor_part is an expression, it shall not be dynamically tagged. The type of the extension_aggregate shall be a descendant of the type of the ancestor_part (the ancestor type), through one or more record extensions (and no private extensions). If the ancestor_part is a subtype_mark, the view of the ancestor type from which the type is descended (see 7.3.1) shall not have unknown discriminants.
5.1/5
If the type of the ancestor_part is limited and at least one component is needed in the record_component_association_list, then the ancestor_part shall not have an operative constituent expression (see 4.4) that is a call to a function with an unconstrained result subtype.

#### Static Semantics

6
For the record_component_association_list of an extension_aggregate, the only components needed are those of the composite value defined by the aggregate that are not inherited from the type of the ancestor_part, plus any inherited discriminants if the ancestor_part is a subtype_mark that denotes an unconstrained subtype.

#### Dynamic Semantics

7
For the evaluation of an extension_aggregate, the record_component_association_list is evaluated. If the ancestor_part is an expression, it is also evaluated; if the ancestor_part is a subtype_mark, the components of the value of the aggregate not given by the record_component_association_list are initialized by default as for an object of the ancestor type. Any implicit initializations or evaluations are performed in an arbitrary order, except that the expression for a discriminant is evaluated prior to any other evaluation or initialization that depends on it.
8/3
If the type of the ancestor_part has discriminants and the ancestor_part is not a subtype_mark that denotes an unconstrained subtype, then a check is made that each discriminant determined by the ancestor_part has the value specified for a corresponding discriminant, if any, either in the record_component_association_list, or in the derived_type_definition for some ancestor of the type of the extension_aggregate. Constraint_Error is raised if this check fails.
9/5
NOTE 1 By the rules given in 4.3.1, if all components of the value of the extension_aggregate are determined by the ancestor_part, then the record_component_association_list will be simply null record.
10
NOTE 2 If the ancestor_part is a subtype_mark, then its type can be abstract. If its type is controlled, then as the last step of evaluating the aggregate, the Initialize procedure of the ancestor type is called, unless the Initialize procedure is abstract (see 7.6).

#### Examples

11
Examples of extension aggregates (for types defined in 3.9.1):
12
Painted_Point'(Point with Red)
(Point'(P) with Paint => Black)
13/5
(Expression with Left => new Literal'(Value => 1.2),
Right => new Literal'(Value => 3.4))
Addition'(Binop with null record)
-- presuming Binop is of type Binary_Operation

Ada 2005 and 2012 Editions sponsored in part by Ada-Europe