AI22-0111-1
!standard 4.3(3/5) 25-03-24 AI22-0111-1/03
!standard 4.3.5(22/5)
!standard 4.3.5(54/6)
!class Binding Interpretation 24-07-06
!status Amendment 1-2022 24-07-18
!status WG9 Approved 25-07-18
!status WG9 Approved 24-10-10
!status ARG Approved 8-0-0 24-07-18
!status work item 24-07-06
!status received 24-07-06
!submitter Tucker Taft
!priority Low
!difficulty Easy
!qualifier Omission
!subject Class-wide Container Aggregates
Allow a class-wide type as the expected type for a container aggregate, provided it is rooted at a type that specifies the Aggregate aspect.
4.3(4/5) allows container aggregates to have a class-wide type. Moreover, the Aggregate aspect is nonoverridable. This means that all types derived from the associated type will allow container aggregates. For tagged types, this additionally means that dispatching calls are allowed. Thus, it clearly was the intent to allow class-wide aggregates. However, the details of this dispatching are missing from 4.3.5. It appears that such an aggregate should be treated roughly like a tag-indeterminate expression.
For example:
type T is tagged ...
with Aggregate => (...);
procedure Fun (X : in out T'Class) is
begin
X := [.....];
-- This aggregate should be treated as a
-- tag-indeterminate expression
end Fun;
Should this sort of class-wide assignment be legal? (Yes.)
All container aggregates start out with a call on either the Empty or the New_Indexed function. Calls on these functions are generally tag-indeterminate in a context where the expected type is class-wide, so we should be able to treat a container aggregate, from a Name Resolution point of view, analogously to calls on such functions.
There are two Name Resolution rules that need to be modified to allow class-wide types as the expected type, plus an addition to the general discussion of what the various subprogram calls mean when evaluating the aggregate.
Modify 4.3(3/5):
The expected type for an aggregate shall be a single array type, a single type with the Aggregate aspect specified{ (or a class-wide type rooted at such a type)}, or a single descendant of a record type or of a record extension.
Modify 4.3.5(22/5):
The expected type for a container_aggregate shall be a single type for which the Aggregate aspect has been specified{, or a class-wide type rooted at such a type}. The expected type for each expression of a container_aggregate is the element type of the expected type.{ For the purposes of this subclause, the expected type has an Aggregate aspect if it is class-wide and the aspect has been specified for its root type.}
Modify 4.3.5(54/6):
When the above wording says that a subprogram is invoked or called, this is a subprogram call as defined in 6.4, with parameter associations as specified in the wording evaluated as defined 6.4.1. [Redundant: In particular, this means that the parameters are converted to the subtype of the formal parameter (which can raise an exception — see 4.6).]{ Furthermore, if the expected type is class-wide, the semantics defined in 3.9.2 for tag-indeterminate expressions apply to the call on Empty or New_Indexed, and those for controlling tags apply to the (dispatching) calls on Add_Named, Add_Unnamed, and Assign_Indexed.}
Because the Aggregate aspect is nonoverridable, the operations specified by the Aggregate aspect would be meaningful for a class-wide type rooted at the associated type (presuming it is tagged). Therefore, there is no problem allowing container aggregates when the expected type is such a class-wide type.
See the !issue section for an example, which should become legal with this feature.
@drepl
The expected type for an @fa{aggregate} shall be a single array type, a single type with the Aggregate aspect specified, or a single descendant of a record type or of a record extension.
@dby
The expected type for an @fa{aggregate} shall be a single array type, a single type with the Aggregate aspect specified (or a class-wide type rooted at such a type), or a single descendant of a record type or of a record extension.
@drepl
The expected type for a @fa{container_aggregate} shall be a single type for which the Aggregate aspect has been specified. The expected type for each @fa{expression} of a @fa{container_aggregate} is the element type of the expected type.
@dby
The expected type for a @fa{container_aggregate} shall be a single type for which the Aggregate aspect has been specified, or a class-wide type rooted at such a type. The expected type for each @fa{expression} of a @fa{container_aggregate} is the element type of the expected type. For the purposes of this subclause, the expected type @i{has an Aggregate aspect} if it is class-wide and the aspect has been specified for its root type.
@dinsa
@xhang{@xterms{2.}an iteration is performed, and for each value conditionally produced by the iteration (see @ref{5.5} and @ref{5.5.2}) the Add_Unnamed procedure is invoked, with the anonymous object @i{A} as the first parameter and the result of evaluating the @fa{expression} as the second parameter.}
@dby
When the above wording says that a subprogram is invoked or called, this is a subprogram call as defined in @ref{6.4}, with parameter associations as specified in the wording evaluated as defined @ref{6.4.1}. In particular, this means that the parameters are converted to the subtype of the formal parameter (which can raise an exception @emdash see @ref{4.6}). Furthermore, if the expected type is class-wide, the semantics defined in @ref{3.9.2} for tag-indeterminate expressions apply to the call on Empty or New_Indexed, and those for controlling tags apply to the (dispatching) calls on Add_Named, Add_Unnamed, and Assign_Indexed.
ACATS tests should be constructed that use class-wide expected types for the various different sorts of container aggregates.
This is intended to address ARG GitHub issue #61.