Version 1.5 of ais/ai-00331.txt

Unformatted version of ais/ai-00331.txt version 1.5
Other versions for file ais/ai-00331.txt

!standard 10.01.01 (19)          04-11-30 AI95-00331/02
!class binding interpretation 03-07-22
!status Amendment 200Y 04-11-30
!status WG9 Approved 06-06-09
!status ARG Approved 8-0-2 04-11-21
!status work item 04-03-08
!status received 03-04-07
!priority Low
!difficulty Medium
!qualifier Error
!subject 10.1.1(19) doesn't handle multiple nesting?
!summary
A generic child unit can be instantiated regardless of its level, by instantiating a copy of the child unit declared within an instance of a generic corresponding to the child's parent unit.
!question
Is the following legal?
generic package Pak1 is end Pak1;
generic package Pak1.Pak2 is end Pak1.Pak2;
generic package Pak1.Pak2.Pak3 is end Pak1.Pak2.Pak3;
with Pak1.Pak2.Pak3; procedure Test is package New_Pak1 is new Pak1; package New_Pak2 is new New_Pak1.Pak2; -- OK package New_Pak3 is new New_Pak2.Pak3; -- LEGAL? (Yes.) begin null; end Test;
A careful reading of 10.1.1(19) suggests that it is not. 10.1.1(19) says
"For each declaration or renaming of a generic unit as a child of some
parent generic package, there is a corresponding declaration nested immediately within each instance of the parent. This declaration is visible only within the scope of a with_clause that mentions the child generic unit."
This clause makes the second instantiation, marked "OK", legal. Pak1.Pak2 is a child of a parent generic package Pak1. New_Pak1 is an instance of Pak1. Therefore, by this clause, there is a corresponding declaration Pak2 nested immediately within New_Pak1. This corresponding declaration, New_Pak1.Pak2, is visible because of the with clause that mentions Pak1.Pak2.
However, the same logic can't be applied to make the third instantiation legal. Pak1.Pak2.Pak3 is a child of the parent generic package Pak1.Pak2. New_Pak2 is an instance of New_Pak1.Pak2 (which was created by the declaration of New_Pak1), not an instance of Pak1.Pak2.
Given that New_Pak2 is not an instance of Pak1.Pak2, 10.1.1(19) does not apply, since New_Pak2 is not a library unit and thus cannot have children. The conclusion seems to be that there is no such "corresponding declaration" that declares New_Pak2.Pak3, and thus the third instantiation is not legal.
Is this intended? (No.)
!recommendation
(See wording.)
!wording
Replace 10.1.1(19):
For each declaration or renaming of a generic unit as a child of some parent generic package, there is a corresponding declaration nested immediately within each instance of the parent. This declaration is visible only within the scope of a with_clause that mentions the child generic unit.
with
For each child C of some parent generic package P, there is a corresponding declaration C nested immediately within each instance of P. For the purposes of this rule, if a child C itself has a child D, each corresponding declaration for C has a corresponding child D. The corresponding declaration for a child within an instance is visible only within the scope of a with_clause that mentions the (original) child generic unit.
!discussion
It was obviously the intent that it be possible to instantiate generic child units declared deeper than one level below a parent generic unit. However, the current wording of 10.1.1(19) is insufficient to allow such instantiations because it only defines corresponding declarations appearing within instances of a generic child's parent unit. The problem is that once the generic child unit is deeper than the second level, the parent generic unit is itself a child, and there are no (direct) instances of that parent. Rather, there can only be instances of a corresponding declaration of the parent generic. This is addressed by the addition of a clarifying rule that specifies that a corresponding declaration has corresponding child units.
!corrigendum 10.01.01(19)
Replace the paragraph:
For each declaration or renaming of a generic unit as a child of some parent generic package, there is a corresponding declaration nested immediately within each instance of the parent. This declaration is visible only within the scope of a with_clause that mentions the child generic unit.
by:
For each child C of some parent generic package P, there is a corresponding declaration C nested immediately within each instance of P. For the purposes of this rule, if a child C itself has a child D, each corresponding declaration for C has a corresponding child D. The corresponding declaration for a child within an instance is visible only within the scope of a with_clause that mentions the (original) child generic unit.
!ACATS test
Create an ACATS test similar to the example in the question.
!appendix

!topic 10.1.1(19) doesn't handle multiple nesting?
!reference RM95 10.1.1(19)
!from Adam Beneschan 04-07-03
!discussion

Is the following source legal?

    generic
    package pak1 is
    end pak1;

    generic
    package pak1.pak2 is
    end pak1.pak2;

    generic
    package pak1.pak2.pak3 is
    end pak1.pak2.pak3;

    with pak1.pak2.pak3;
    procedure test19 is
        package new_pak1 is new pak1;
        package new_pak2 is new new_pak1.pak2;   -- OK
        package new_pak3 is new new_pak2.pak3;   -- LEGAL?
    begin
        null;
    end test19;

I had always assumed this was legal, and GNAT compiles it.  However,
after reading RM 10.1.1(19) carefully, I do not think is legal the way
the RM is currently worded.  My conclusion is that the RM wording is
incorrect and needs to be fixed.

10.1.1(19) reads: "For each declaration or renaming of a generic unit
as a child of some parent generic package, there is a corresponding
declaration nested immediately within each instance of the parent.
This declaration is visible only within the scope of a with_clause
that mentions the child generic unit."

This clause makes the second instantiation, marked "OK", legal.
pak1.pak2 is a child of a parent generic package, where the parent
package is pak1.  new_pak1 is an instance of the parent, pak1.
Therefore, by this clause, there is a corresponding declaration pak2
nested immediately within new_pak1.  This corresponding declaration,
new_pak1.pak2, is visible because of the WITH clause that mentions
pak1.pak2 (it's a _prefix_ of pak1.pak2.pak3, therefore it's
"mentioned"---see 10.1.2(6)).

However, the same logic can't be applied to make the third
instantiation legal.  pak1.pak2.pak3 is a child of a parent generic
package, where the parent package is pak1.pak2.  new_pak2 is an
instance of---what?  It's actually an instance of new_pak1.pak2 (which
was created by the declaration of new_pak1), not an instance of
pak1.pak2.  I can't find anything in Section 12 that would allow
new_pak2 to be considered an instance of pak1.pak2.  (Unless you
interpret the undefined phrase "original generic unit" in 12(1) to
mean that!  However, I suspect that interpretation might lead to other
problems in nested generic cases.)

So given that new_pak2 is not an instance of pak1.pak2, 10.1.1(19)
does not apply, since new_pak2 is not a library unit and thus cannot
have children.  The conclusion seems to be that there is no such
"corresponding declaration" that declares new_pak2.pak3, and thus the
third instantiation is not legal.

Since this interpretation of the RM would mean that three-level
generic child units cannot be instantiated and are therefore useless,
I have to conclude that either the wording of the RM (probably
10.1.1(19)) is in error, or I've missed something elsewhere in the RM
that would straighten this out.

Am I missing something?

*************************************************************


Questions? Ask the ACAA Technical Agent