!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) @drepl 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 @fa that mentions the child generic unit. @dby For each child @i of some parent generic package @i

, there is a corresponding declaration @i nested immediately within each instance of @i

. For the purposes of this rule, if a child @i itself has a child @i, each corresponding declaration for @i has a corresponding child @i. The corresponding declaration for a child within an instance is visible only within the scope of a @fa 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? *************************************************************