Version 1.2 of ai22s/ai22-0005-1.txt
!standard 6.6 (6) 21-11-11 AI22-0005-1/00
!class confirmation 21-11-11
!status received 21-11-11
!priority Low
!difficulty Easy
!qualifier Omission
!subject Editorial comments on AARM 2022
!summary
This AI serves as a holder for editorial comments on AARM-only
annotations. This AI serves the same purpose as AI95-00114 did for Ada 2005,
AI05-0005-1 did for Ada 2012, and AI12-0005-1 did for Ada 2022. Because the
AARM has no official status as far as ISO is concerned, these will be
considered low priority.
If a change cross-references this AI, find it in the Appendix below.
!question
!response
!appendix
From: John Barnes
Sent: Tuesday, May 22, 2021 xx:xx PM
... [Placeholder for the moment.]
****************************************************************
Editor's note (Nov 8, 2021): All of the items above this
marker have been included in the working version of the AARM.
****************************************************************
From: Steve Baird [privately]
Sent: Tuesday, August 24, 2021 7:20 PM
We have the inheritance rule in 13.1(15.5):
if the name denotes one or more primitive subprograms of the type, the
inherited aspect is a name that denotes the corresponding primitive
subprogram(s) of the derived type;
For tagged types, I think the meaning of the above rule is clear, at least in
the context of inherited Integer_Literal, Real_Literal, and String_Literal
aspects (because for those we don't care about things like formal parameter
names and default expressions). If a primitive subprogram for a tagged type
has more than one view floating around, we don't care much about which one
we get. See, for example, the words "[even if the declaration occurs in
a private part]" in 3.9.2(20.1).
But let's look at an untagged example with an overriding function declared
in the private part of the enclosing package:
procedure Foo is
pragma Assertion_Policy (Check);
package Pkg1 is
type Parent_Type is record X, Y : Integer; end record
with Integer_Literal => I_L;
function I_L (S : String) return Parent_Type is (0, 0);
end Pkg1;
package Pkg2 is
type Descendant is new Pkg1.Parent_Type;
private
overriding function I_L (S : String) return Descendant is (1, 1);
end Pkg2;
package Client is
D : Pkg2.Descendant := 123;
end Client;
begin
pragma Assert (Client.D = ???);
end Foo;
What value should be assigned to Client.D?
4.2.1(7) says that evaluating the literal 123 is "is equivalent to a call to
the subprogram denoted by the corresponding aspect of T".
And that takes us to 13.1(15.5) and the word "corresponding".
It seems desirable to me that if an integer literal can be interpreted as an
expression of a non-numeric type, then all integer literals of that type ought
to generate calls to the same subprogram, regardless of where each literal
occurs.
FWIW, the phrase "corresponding primitive" occurs on 11 different RM pages.
Hopefully they have consistent meanings.
What do you think?
****************************************************************
From: Randy Brukardt [privately]
Sent: Wednesday, August 25, 2021 9:59 PM
[Editor's note: I removed the bulk of this private thread, which had many
false starts and confusions. I've just left parts relevant to the conclusion.]
[Tuck replied in part: "Yes, I agree we want to call the overriding function,
even if it is not visible. So some wording should be provided to clarify that."]
That would be wildly incompatible (assuming you are speaking generally, which
is how I interpreted this). Overriding of untagged operations is purely a
visibility thing, hiding the inherited version. It doesn't have an effect on
calls.
I suppose we could have nonoverridable aspects work differently than other
untagged overridding, but that would be extremely strange. If we really want
to do that, we probably should decouple that from overriding, since they would
work completely differently. (And I agree how stream attributes work, but they
don't have anything to do with overriding, presumably for this reason).
...
****************************************************************
From: Tucker Taft [privately]
Sent: Wednesday, August 25, 2021 8:29 AM
> That would be wildly incompatible (assuming you are speaking generally,
> which is how I interpreted this). Overriding of untagged operations is
> purely a visibility thing, hiding the inherited version. It doesn't have
> an effect on calls.
I was not talking generally, but was rather suggesting this should be a
special case for non-overridable aspects, but I have changed my mind. In
general when you specify an aspect, it must be resolved before the end of the
immediately enclosing declaration list, so anything that happens after that
should be irrelevant for an untagged type. So I now say it should return
(0,0) whether or not you can see the private overriding. Hopefully compilers
will give a warning if you override a primitive of an untagged type in the
private part, as that is generally a misleading thing to do.
In any case we need to clarify what happens in this case. I would say the
inherited aspect needs to be resolved within the same declaration list as the
derived type declaration, and once resolved, it is "sticky" and is not
affected by a subsequent overriding of the operation.
> I suppose we could have nonoverridable aspects work differently than other
> untagged overridding, but that would be extremely strange. If we really want
> to do that, we probably should decouple that from overriding, since they
> would work completely differently. (And I agree how stream attributes work,
> but they don't have anything to do with overriding, presumably for this
> reason).
I am now in agreement with you that nonoverridable aspects of untagged types
should work the same as calls on a primitive of a untagged type, which means
overriding in a private part is almost always a mistake.
...
****************************************************************
From: Steve Baird [privately]
Sent: Wednesday, August 25, 2021 2:16 PM
Would an AARM note (and no other change) be appropriate?
Perhaps immediately after 13.1(15.5):
AARM Note: A subprogram declared after the end of the enclosing
declaration list of the derived type (in particular, in the private
part of a package if the derived type is declared in the package's
visible part) is never considered to be "corresponding" with respect
to this rule.
****************************************************************
From: Tucker Taft [privately]
Sent: Wednesday, August 25, 2021 4:01 PM
[Editor's note: After several rounds of wordsmithing, removed here.]
I knew you would have exactly this objection... ;-) I told the truth, but
not the whole truth! I thought that was OK in a note, but the whole-truth
police caught me. So perhaps:
AARM Note: A primitive subprogram that is declared after the end of the
enclosing declaration list of a derived type (in particular, in the private
part of a package if the derived type is declared in the package's visible
part) is not the "corresponding primitive subprogram" in the sense of this
rule. In a case like this, the corresponding primitive subprogram is
actually the inherited subprogram. This doesn't make a difference for
tagged types, because of the "dispatching" semantics used, which means a
call on the inherited subprogram actually "reaches" the body of the
overriding. But for untagged types, overriding an inherited subprogram of
an untagged derived type in the private part is "too late" to have an effect
on external uses of the primitive, since non-visible overridings are not
generally reachable, and a call that only "sees" the inherited subprogram
goes to the body of the parent's operation, effectively ignoring the
private overriding. This same rule applies to aspects that denote an
inherited subprogram of an untagged derived type -- the private overriding
is effectively ignored.
****************************************************************
From: Jeff Cousins [privately]
Sent: Tuesday, November 9, 2021 3:16 AM
4.3.3(15.2/5) The AI given in the AARM is wrong, it should be AI12-0236-1
not AI05-0147-1.
****************************************************************
Questions? Ask the ACAA Technical Agent