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.]
Language Design Principles
1.a
The model underlying this syntax is that a record
extension can also be viewed as a regular record type with an ancestor
"prefix." The record_component_association_list
corresponds to exactly what would be needed if there were no ancestor/prefix
type. The ancestor_part determines the value
of the ancestor/prefix.
Syntax
2
extension_aggregate ::=
(
ancestor_part with record_component_association_list)
3
ancestor_part ::= expression |
subtype_mark
Name Resolution Rules
4/2
{
AI95-00287-01}
{expected type (extension_aggregate)
[partial]} The expected type for an
extension_aggregate
shall be a single
nonlimited type that is
a record extension.
{expected type (extension_aggregate
ancestor expression) [partial]} If the
ancestor_part is an
expression,
it is expected to be of any
nonlimited tagged
type.
4.a
Reason: We could have made the expected
type T'Class where T is the ultimate ancestor of the type
of the aggregate, or we could have made it even more specific than that.
However, if the overload resolution rules get too complicated, the implementation
gets more difficult and it becomes harder to produce good error messages.
Legality Rules
5/2
{
AI95-00306-01}
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 derived from the type of the
ancestor_part,
through one or more record extensions (and no private extensions).
5.a/2
Reason: {
AI95-00306-01}
The expression cannot be dynamically tagged to
prevent implicit "truncation" of a dynamically-tagged value
to the specific ancestor type. This is similar to the rules in 3.9.2.
Static Semantics
6
{needed component
(extension_aggregate record_component_association_list)} 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
{evaluation (extension_aggregate)
[partial]} 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
{Discriminant_Check
[partial]} {check,
language-defined (Discriminant_Check)} If
the type of the
ancestor_part has discriminants
that are not inherited by the type of the
extension_aggregate,
then, unless the
ancestor_part is a
subtype_mark
that denotes an unconstrained subtype, a check is made that each discriminant
of the ancestor has the value specified for a corresponding discriminant,
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 (raised by failure
of run-time check)} Constraint_Error is
raised if this check fails.
8.a
Ramification: Corresponding and specified
discriminants are defined in
3.7. The rules
requiring static compatibility between new discriminants of a derived
type and the parent discriminant(s) they constrain ensure that at most
one check is required per discriminant of the ancestor expression.
9
8 If all components of the value of the
extension_aggregate are determined by the
ancestor_part, then the record_component_association_list
is required to be simply null record.
10
9 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
(Expression with Left => 1.2, Right => 3.4)
Addition'(Binop with null record)
-- presuming Binop is of type Binary_Operation
Extensions to Ada 83
13.a
{
extensions to Ada 83}
The
extension aggregate syntax is new.
Incompatibilities With Ada 95
13.b/2
{
AI95-00306-01}
{incompatibilities with Ada 95} Amendment
Correction: Eliminated implicit “truncation” of a dynamically
tagged value when it is used as an ancestor expression.
If an aggregate includes such an expression,
it is illegal in Ada 2005. Such aggregates
are thought to be rare; the problem can be fixed with a type conversion
to the appropriate specific type if it occurs.
Wording Changes from Ada 95
13.c/2
{
AI95-00287-01}
Limited extension_aggregates
are allowed (since all kinds of aggregates can now be limited, see 4.3).