AI22-0159-1
!standard 4.1.6(2/7) 26-05-12 AI22-0159-1/02
!standard 4.1.6(3/7)
!standard 13.1(5.5/5)
!standard 13.1.1(8/6)
!class Binding Interpretation 26-03-18
!status Revision-202Y 26-05-12
!status ARG Approved 9-0-1 26-05-12
!status work item 26-03-13
!status received 26-03-13
!assigned author Tucker Taft
!submitter Gary Dismukes
!priority Medium
!difficulty Medium
!qualifier Clarification
!subject Inheritance for aspects allowed to denote multiple subprograms
For a type-related aspect that is allowed to denote multiple subprograms satisfying a single (partial) expected profile, and is also defined to be inherited, the rules for inheritance are clarified. In particular, if the aspect denotes one or more nonprimitive subprograms, they cannot be overridden. An aspect that denotes primitives follows a somewhat different rule. The primitive subprograms denoted by such an aspect can be overridden, and any additional primitives of the same name, satisfying the expected profile, are automatically included. This is not dependent on whether the aspect is confirmed.
The general rules for an aspect, such as an indexing aspect (RM 4.1.6), that allows multiple denoted subprograms (RM 13.1(15.2/5-15.8/5)), do not clearly explain the rules for overriding or augmenting the set of denoted subprograms in a derived type. It is also unclear whether the rules for overriding or augmenting depend on whether or not the aspect is explicitly confirmed.
As an example:
package Indexable is
type String_Map is tagged private
with Constant_Indexing => Index;
function Index (A : String_Map; X : String) return String;
-- return associated string
...
end Indexable;
with Indexable;
package Derived is
type Fine_String_Map is new Indexable.String_Map with
private
with Constant_Indexing => Index;
-- does this explicit confirmation matter?
function Index (A : Fine_String_Map; X : String; N : Positive)
return Character;
-- return Nth character of string
–- Is this usable for indexing in the absence of
-- the confirming aspect spec?
...
end Derived;
In the above, do we need the confirming aspect specification to have the set of indexing functions be augmented by the function returning a Character? (No)
How does this change if the Index function defined in Indexable takes String_Map'Class instead of String_Map? (It becomes illegal)
We should clarify the rules to indicate that, whether or not the aspect is explicitly confirmed, additional primitive subprograms that satisfy the requirements for the aspect are included, presuming the original aspect denoted one or more primitive subprograms. On the other hand, for the case where the original denoted subprograms were not primitive subprograms, we should clarify that the aspect continues to denote the original subprograms, and no others. It is not possible to override or augment the set of denoted subprograms in this case. Furthermore, it is not possible to explicitly confirm such an aspect, because of the complexity that would be required to enable such a confirming aspect to be resolved to denote the original subprograms.
Modify 4.1.6(2/7) [Ed. note: modification relative to AI22-0154-1]
This aspect shall be specified by a name that denotes one or more functions. [When directly specified, the]{The} expected profile of this aspect is satisfied by every function that has at least two parameters, the first of which is of type T or, if T is a tagged type, T'Class, or is an access parameter designating one of these types.{ The first parameter of such a function shall be of mode in[a][b][c];}[ If the first parameter of such a function]{ if it} is an access parameter, it shall be an access-to-constant parameter.
Modify 4.1.6(3/7): [Ed. note: modification relative to AI22-0154-1]
This aspect shall be specified by a name that denotes one or more functions. [When directly specified, the]{The} expected profile of this aspect is satisfied by every function that has at least two parameters, the first of which is of type T or, if T is a tagged type, T'Class, or is an access parameter designating one of these types. All such functions shall have an explicitly aliased variable result, or a return type that is a reference type (see 4.1.5), whose reference discriminant is of an access-to-variable type.
Modify 13.1(15.5/5):
Modify 13.1.1(18.2/5):
If a given aspect is type-related and {defined to be inherited by descendants}[inherited], then within an aspect_definition for the aspect, if a name resolves to denote multiple visible subprograms, all or none of the denoted subprograms shall be primitives of the associated type.{ Similarly, in a derived type where the aspect is not directly specified, if the type inherits a primitive subprogram denoted by the aspect, there shall be no subprograms that have the same designator as this primitive that also satisfy the requirements of the expected profile, but are not primitives of the derived type; if the subprograms denoted by the aspect in an ancestor are not primitive subprograms, there shall be no subprogram declared immediately within the same declarative region as the derived type that has the same designator as the denoted subprograms that also satisfies the requirements of the expected profile. In a derived type inheriting such an aspect, the aspect shall be confirmed only if the original subprograms denoted in the ancestor were primitive subprograms. [Redundant: If they are nonprimitives, the aspect cannot be confirmed.]
AARM Reason: We disallow confirmation for such aspects when the original subprograms were nonprimitive because of the complexity of the rules that would be required to resolve the name used in an explicitly confirming aspect. The name would need to denote subprograms that were visible where the ancestor was declared, perhaps with a different expected profile.}
The goal of this AI is to clarify the rules for aspects that can denote multiple subprograms all satisfying the same (partial) expected profile. We try to ensure that when such aspects are inherited, a confirming aspect specification is permitted, and has exactly the same effect as not confirming it. Furthermore, if the original denoted subprograms are primitives, then on a derived type, any other subprograms with the same identifier are not ignored if they satisfy the expected profile. They are illegal if they would produce a combination of primitives and nonprimitives. If they are all primitives, the additional primitives are included in the set of denoted subprograms.
If the original denoted subprogram(s) are not primitives, then the rules are a bit different. In the derived type, the aspect denotes the same set of nonprimitive subprograms, and there is no way to override that. Furthermore, the aspect cannot be explicitly confirmed in this case, due to the complexity of resolving the name which would have to denote subprograms likely declared elsewhere, and which might not satisfy the expected profile for the aspect because their classwide operand was rooted at an ancestor type, rather than the derived type.
See !Issue.
@drepl
@xhang{@xterm{Constant_Indexing}This aspect shall be specified by a @fa{name} that denotes one or more functions. When directly specified, the expected profile of this aspect is satisfied by every function that has at least two parameters, the first of which is of type @i{T} or, if @i{T} is a tagged type, @i{T}'Class, or is an access parameter designating one of these types. If the first parameter of such a function is an access parameter, it shall be an access-to-constant parameter.}
@dby
@xhang{@xterm{Constant_Indexing}This aspect shall be specified by a @fa{name} that denotes one or more functions. The expected profile of this aspect is satisfied by every function that has at least two parameters, the first of which is of type @i{T} or, if @i{T} is a tagged type, @i{T}'Class, or is an access parameter designating one of these types. The first parameter of such a function shall be of mode @b{in}; if it is an access parameter, it shall be an access-to-constant parameter.}
@drepl
@xhang{@xterm{Variable_Indexing}This aspect shall be specified by a @fa{name} that denotes one or more functions. When directly specified, the expected profile of this aspect is satisfied by every function that has at least two parameters, the first of which is of type @i{T} or, if @i{T} is a tagged type, @i{T}'Class, or is an access parameter designating one of these types. All such functions shall have an explicitly aliased nonconstant result, or a return type that is a reference type (see @ref{4.1.5}), whose reference discriminant is of an access-to-variable type.}
@dby
@xhang{@xterm{Variable_Indexing}This aspect shall be specified by a @fa{name} that denotes one or more functions. The expected profile of this aspect is satisfied by every function that has at least two parameters, the first of which is of type @i{T} or, if @i{T} is a tagged type, @i{T}'Class, or is an access parameter designating one of these types. All such functions shall have an explicitly aliased nonconstant result, or a return type that is a reference type (see @ref{4.1.5}), whose reference discriminant is of an access-to-variable type.}
@drepl
@xinbull{if the @fa{name} denotes one or more primitive subprograms of the type, the inherited aspect is a @fa{name} that denotes the corresponding primitive subprogram(s) of the derived type;}
@dby
@xinbull{if the @fa{name} denotes one or more primitive subprograms of the type, the inherited aspect is a @fa{name} that denotes the corresponding primitive subprogram(s) of the derived type, as well as any other primitive subprograms of the derived type with the same identifier that satisfy the requirements of the expected profile;}
@drepl
If a given aspect is type-related and inherited, then within an @fa{aspect_definition} for the aspect, if a @fa{name} resolves to denote multiple visible subprograms, all or none of the denoted subprograms shall be primitives of the associated type.
@dby
If a given aspect is type-related and defined to be inherited by descendants, then within an @fa{aspect_definition} for the aspect, if a @fa{name} resolves to denote multiple visible subprograms, all or none of the denoted subprograms shall be primitives of the associated type. Similarly, in a derived type where the aspect is not directly specified, if the type inherits a primitive subprogram denoted by the aspect, there shall be no subprograms that have the same designator as this primitive that also satisfy the requirements of the expected profile, but are not primitives of the derived type; if the subprograms denoted by the aspect in an ancestor are not primitive subprograms, there shall be no subprogram declared immediately within the same declarative region as the derived type that has the same designator as the denoted subprograms that also satisfies the requirements of the expected profile. In a derived type inheriting such an aspect, the aspect shall be confirmed only if the original subprograms denoted in the ancestor were primitive subprograms. If they are nonprimitives, the aspect cannot be confirmed.
ACATS B-Tests and C-Tests are needed to check these rules. Some existing ACATS tests might need modification for these rules.
This AI arose out of private discussions about the corrections of AI22-0154-1, in particular understanding what the rules are for inheritance of derived types.
[a]This change is incompatible, and not directly pertinent to this AI's subject matter, but I suppose it's OK if there's general agreement about it.
[b]Agreed; there is no such rule currently. Perhaps there ought to have been, but it seems rather late to be adding such a requirement.
[c]I believe it was an oversight, and we should fix it as part of this AI (or AI22-0154-1). It really makes no sense to have an IN OUT parameter (or an OUT parameter!).