Version 1.2 of ais/ai-00331.txt

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

!standard 10.01.01 (19)          04-03-08 AI95-00331/01
!class binding interpretation 03-07-22
!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 declaration or renaming of a generic unit as a child of some parent generic package, there is a corresponding declaration nested immediately within {the visible part of} each instance of the parent. {Similarly, nested immediately within each instance of such a corresponding declaration for a generic child package, there is a corresponding declaration for each child of that generic child package.} {Such a corresponding generic declaration} is visible only within the scope of a with_clause that mentions the child generic unit.
(Question: Does 12.2(2) require any modification? Any other paragraphs?)
!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 rule that further specifies corresponding declarations of generic child units as occurring within instances of their parent generic's corresponding declarations.
An additional correction is to clarify that a generic child's corresponding declaration occurs within the visible part of an instance associated with the parent (rather than in some other location, such as within the private part).
--!corrigendum 10.01.01(19)
!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