CVS difference for ais/ai-00202.txt

Differences between 1.2 and version 1.3
Log of other versions for file ais/ai-00202.txt

--- ais/ai-00202.txt	1998/10/03 04:28:56	1.2
+++ ais/ai-00202.txt	1999/03/22 18:22:07	1.3
@@ -1,4 +1,4 @@
-!standard 12.05.01 (21)                               98-10-02  AI95-00202/01
+!standard 12.05.01 (21)                               99-03-21  AI95-00202/02
 !class binding interpretation 98-03-27
 !status work item 98-10-02
 !status received 98-03-27
@@ -6,15 +6,16 @@
 !difficulty Hard
 !subject Primitives of formal type derived from another formal type
 
-!summary 98-10-02
+!summary 99-03-21
 
-When the ancestor type of a formal derived type is itself a formal type,
-then within an instance, the copies of the formal derived type's inherited
-primitive operations declare views of the formal ancestor type's operations.
+In an instance of a generic unit having a formal derived type whose ancestor
+is itself a formal type, the copies of the implicit subprogram declarations
+of the formal derived type declare views of the corresponding copies of the
+primitive subprograms of the formal ancestor type.
 
-!question 98-10-02
+!question 99-03-21
 
-In an instance of a generic where a formal derived type whose ancestor type
+In an instance of a generic with a formal derived type whose ancestor type
 is another formal type, the rules regarding the meanings of the implicit
 declarations for the formal derived type produce a peculiar result.
 
@@ -35,13 +36,13 @@
    procedure G (o2 : F2; o3 : F3) is
    begin
       S(o2);
-      S(o3);                                 -- Peculiar result
+      S(o3);                                 -- Peculiar result: Calls S (5)?
    end G;
 
    package P2 is
       type R2 is new R1;
       -- implicit: procedure S (x : R2);     -- (4)
-      procedure S (x : R2);                  -- (5)
+      procedure S (x : out R2);              -- (5) Overriding with mode out
    end P2;
    use P2;
 
@@ -64,135 +65,115 @@
 the instance, which is R2.  So, the implicit declaration of S that operates
 on F3 (3) is a view of the corresponding primitive subprogram of R2 (5).
 But, the annotation in AARM 12.5.1(21.a) indicates that the reason the
-primitives of a formal derived type in an instance are views of its ancestor's
-primitives is because the primitives of its actual type might not be subtype
-conformant with those of its ancestor type.  This intention could be violated
-if the primitive S (3) is a view of the primitive S (5).
+primitives of a formal derived type in an instance are views of its
+ancestor's primitives is because the primitives of its actual type might not
+be subtype conformant with those of its ancestor type.  This intention could
+be violated if the primitive S (3) is a view of the primitive S (5).
 
-Is it the intent that the primitive S (3) should instead declare a view
-of S (1)? (Yes.)
+Is it the intent that the primitive S (3) should declare a view of S (1)?
+[Yes.]
 
 In general, when the ancestor type of a formal derived type is itself
 another formal type, then within an instance does the derived type
 acquire the primitive operations of the formal ancestor type or the
 primitive operations of the ancestor type's corresponding actual type?
-(The derived type within the instance declares copies that are views
-of the operations of the formal ancestor type.)
 
-!recommendation 98-10-02
-
-When the ancestor type of a formal derived type is itself a formal type,
-then within an instance, the copies of the formal derived type's inherited
-primitive operations declare views of the formal ancestor type's operations,
-not views of the operations of the ancestor's corresponding actual type
-as suggested by 12.5.1(21).
-
-!wording 98-10-02
-
-???
-Revise 12.5.1(21) to say:
-
-  "... In an instance, the copy of such an implicit declaration declares
-   a view of the corresponding primitive subprogram {declared for the
-   ancestor type in the generic unit} [of the ancestor], ..."
-???
-
-!discussion 98-10-02
-
-The rule that defines the meaning of inherited operations of formal
-derived types (RM95-12.5.1(21)) states:
-
-  "For a formal derived type, the predefined operators and inherited
-   user-defined subprograms are determined by the ancestor type, and are
-   implicitly declared at the earliest place, if any, within the immediate
-   scope of the formal type, where the corresponding primitive subprogram
-   of the ancestor is visible (see 7.3.1).  In an instance, the copy of
-   such an implicit declaration declares a view of the corresponding primitive
-   subprogram of the ancestor, even if this primitive has been overridden for
-   the actual type."
-
-The second sentence asserts that the instance view of a formal derived
-type's primitive subprograms come from the ancestor type.  This rule
-is designed to avoid the semantic problems that could arise for an untagged
-formal derived type when the corresponding actual type has an overriding
-primitive subprogram that is not subtype conformant with the operation
-inherited from the ancestor.  For instance, the subtypes or modes of the
-actual subprogram might differ from that of the inherited subprogram
-leading to nonsense for calls made to the formal derived type's
-subprograms from within the generic.
-
-However, the wording of 12.5.1(21) does not properly account for the
-case where the ancestor of the formal derived type is itself a formal
-type.  Consider this example adapted from the example in the !question
-section:
-
-   package P1 is
-      type R1 is new Integer;
-      procedure S (X : in R1);               -- (1)
-   end P1;
-   use P1;
-
-   generic
-      type F2 is new R1;
-      -- implicit: procedure S (X : F2);     -- (2)
-      type F3 is new F2;
-      -- implicit: procedure S (X : F3);     -- (3)
-   procedure G (O2 : F2; O3 : F3);
-   procedure G (O2 : F2; O3 : F3) is
-   begin
-      S(O2);  -- (4) OK: calls view of R1's procedure S
-      S(O3);  -- (5) Call with constant actual: legal?
-   end G;
-
-   package P2 is
-      type R2 is new R1;
-      procedure S (X : in out R2);           -- (6)  Mode changes to 'in out'
-   end P2;
-   use P2;
-
-   package P3 is
-      type R3 is new R2;
-      procedure S (x : in R3);               -- (7)
-   end P3;
-   use P3;
-
-   procedure Instance is new G(R2, R3);
-
-The call to S for type F2 works fine, since 12.5.1(21) defines
-this to call the version of S inherited from type R1.  So even
-though the subprogram S associated with the actual type R2
-has a parameter of mode 'in out', in the instance the call
-at (4) will invoke the inherited subprogram S for type R1,
-which has an 'in' mode parameter.
-
-However, according to 12.5.1(21), the copy for procedure S for formal
-type F3 in Instance should be taken as a view of the corresponding
-operation of the ancestor type, and in the instance "the ancestor
-type" is interpreted as being a copy of the actual type associated
-with the formal ancestor (by virtue of the rules for generic
-instances in 12.3(5)).  Thus, since the actual for the formal
-ancestor type F2 is R2, the call at (5) should map into a call
-to the procedure S belonging to R2.  But the S declared at (7)
-has a parameter of mode 'in out', and that is inconsistent with
-the call at (5), which passes a constant (the in parameter O3)
-as an actual.  Thus we would have a generic contract model
-violation for calls within the body of the generic G.
-
-Clearly the call at (5) should also result in a call to the
-procedure S declared at (1).  In general we want the subprogram
-inherited by a formal derived type in an instance to correspond
-to a subprogram of known profile belonging to some ancestor
-of the immediate ancestor of the formal derived type in question
-(the nearest ancestor with a corresponding explicit subprogram).
-A possible wording that expresses this intent is to say that the
-copy of an inherited subprogram of a formal derived type declares
-a view of the corresponding primitive subprogram declared for the
-ancestor type in the generic unit.  This implicitly accounts for
-the potentially transitive nature of the required view.  [The
-wording may need some adjustment though, since technically it
-doesn't seem completely legitimate to refer to a primitive
-subprogram of a formal ancestor type when in the context of
-an instance, but the intended interpretation is clear enough.]
+[Within the instance, the copies of the implicit operations of the formal
+derived type declare views of the corresponding copied operations of the
+formal ancestor type, not views of the operations of the ancestor's actual
+type.]
+
+!recommendation 99-03-21
+
+The copies of the implicitly declared primitive subprograms of a formal
+derived type in an instance are defined to be views of the ancestor type's
+corresponding operations (12.5.1(21)).  In the case of a formal type whose
+ancestor is another formal type of the same generic unit, this results
+in the undesirable semantics that in an instance, the copies of the first
+formal type's implicitly declared operations are views of the corresponding
+operations of the ancestor type's actual type.
+
+It is essential to ensure that such copied implicit operations are always
+views of a parent type known at the point of the generic formal type's
+declaration, since using the operations of the ancestor's actual type can
+lead to inconsistencies because the operations of an actual (untagged) type
+may not be subtype conformant with those of the formal type.
+
+This AI amends the rule of 12.5.1(21) to correct this problem.  The copies
+of a formal derived type's operations in an instance are defined to be
+views of the corresponding copies of the primitive operations of the
+formal type's ancestor when the ancestor is a formal type, rather than
+simply those of "the ancestor type" (which in an instance would denote
+the actual type associated with the formal type's ancestor).
+
+Note that in the case where the ancestor type is a formal derived type,
+the copied operations of the ancestor type in the instance are themselves
+views of operations coming from the ancestor type's own ancestor (so the
+new rule applies transitively for arbitrary levels of derivation from formal
+derived types).
+
+!wording 99-03-21
+
+The second sentence of 12.5.1(21) should be corrected to cover the case
+where the formal derived type has a formal ancestor type declared in
+the same generic formal part.  The copied operations of the formal
+derived type must be defined to declare views of the corresponding
+copied operations of the ancestor.
+
+!discussion 99-03-21
+
+Paragraph 12.5.1(21) defines the implicit operations that are declared
+for a formal derived type, as well as the meaning of the copies of those
+implicit operations declared within an instance.  The second sentence
+states:
+
+  In an instance, the copy of such an implicit declaration declares
+  a view of the corresponding primitive subprogram of the ancestor,
+  even if this primitive has been overridden for the actual type.
+
+However, in the instance of a generic unit with formal derived type T2
+whose ancestor type is itself a formal derived type T1, the phrase
+"of the ancestor" must be interpreted as referring to the actual
+type A1 associated with the formal ancestor T1.  This is because
+in the instance, the ancestor type of the copy of T2 is a view of the
+actual type A1 associated with T1.  This is the normal interpretation
+of copies of declarations within instances as defined by the static
+semantics in 12.3(13-16).  But that leads to the conclusion that the
+view defined in 12.5.1(21) denotes the corresponding primitive
+subprogram of the ancestor's actual type.
+
+As shown in the example of the !question section, this can result
+in inconsistent views of a formal type's primitive operations,
+since the formal view of a primitive may not be subtype conformant
+with the view in an instance.  For example, modes of parameters may
+differ between the formal and actual views of an subprogram, leading
+to undefined semantics for the copied version of a call to such
+a subprogram from within an instance.  This would essentially
+result in a generic contract model violation in the body of the
+instance.
+
+The Ramification in AARM-12.5.1(21.a) makes the intent behind 12.5.1(21)
+clear, explaining how in the case of untagged types the rule ensures that
+the operations of the type in an instance are those of the ancestor rather
+than those of the actual type, which may not be subtype conformant.
+However the formulation of the rule does not account for cases where the
+ancestor is a formal type itself, whose operations may not be subtype
+conformant with those of a corresponding actual type in an instance.
+
+This AI fixes this problem by specifying that, in an instance, the
+implicit declaration of a primitive subprogram of a formal derived
+type with a formal ancestor declares a view of the corresponding
+copied operation of the ancestor.
+
+If the ancestor is a nonderived formal type, then the copied operations
+of the ancestor declare views of the predefined operators of the ancestor's
+corresponding actual type.
+
+In the case where the ancestor is itself a formal derived type, then
+the copied operations of the ancestor will themselves be views of
+operations coming from the ancestor type's own ancestor, so the rule
+applies transitively for arbitrary levels of derivation from formal
+derived types.
 
 !appendix 98-03-27
 

Questions? Ask the ACAA Technical Agent