CVS difference for ai05s/ai05-0115-1.txt

Differences between 1.10 and version 1.11
Log of other versions for file ai05s/ai05-0115-1.txt

--- ai05s/ai05-0115-1.txt	2011/03/22 05:07:08	1.10
+++ ai05s/ai05-0115-1.txt	2011/04/01 06:38:28	1.11
@@ -1,4 +1,4 @@
-!standard 4.3.2(5/2)                                  11-03-16  AI05-0115-1/06
+!standard 4.3.2(5/2)                                  11-03-30  AI05-0115-1/07
 !standard 7.3.1(5/1)
 !class binding interpretation 08-10-15
 !status work item 08-10-15
@@ -100,6 +100,19 @@
 
 !wording
 
+Add after 3.9(12.2):
+
+   For the purposes of the dynamic semantics of functions Descendant_Tag
+   and Is_Descendant_At_Same_Level, a tagged type T2 is a /descendant/ of
+   a type T1 if it is the same as T1, or if its parent type or one of its
+   progenitor types is a descendant of type T1 by this rule [Redundant:,
+   even if at the point of the declaration of T2, one of the derivations
+   in the chain is not visible].
+
+     AARM Discussion: In other contexts, "descendant" is dependent on visibility,
+     and the particular view a derived type has of its parent type.  See RM 7.3.1.
+
+
 Modify 4.3.2(5/2):
 
   If the ancestor_part is a subtype_mark, it shall denote a specific
@@ -158,6 +171,61 @@
 can never take advantage of having "more" visibility than that of your
 parent type.
 
+The reference manual was scanned to see whether this change to the definition
+of "descendant" would have adverse affects.  It was determined that it fixed
+other potential holes in the language -- see below for more details.  It
+was also decided that the definition of "descendant" for the purposes of
+the run-time semantics of functions like Ada.Tags.Descendant_Tags should
+not depend on "views" even though the static semantics now more-clearly does.
+
+To be precise about where this change has effects:
+
+  In 3.4.1(9-10) we define "derivation class," "ancestor," and "cover," in
+  terms of type derivation and/or descendant. In all cases, this refined
+  definition of "descendant" would have an impact on the question of whether
+  a given type is in a particular derivation class, whether it is covered
+  by the class-wide type of that class, whether the root of the derivation
+  class is an ancestor, etc.
+
+  In 4.6(21-24) on type conversion, there are several uses of the terms
+  "ancestor" and "descended from." With this refined definition of
+  "descendant," these rules would preclude converting to an ancestor of
+  which the parent is not aware. AI95-00157 addresses the question of
+  whether you must use conversion to a grandparent type to gain access
+  to a component that the grandchild type inherits from the grandparent,
+  but which its immediate parent cannot see.  Here we disallow even the
+  conversion to an ancestor if the parent did not "know" about the ancestor.
+
+  In 8.6(21, 25, 25.1, 27.1) whether one type "covers" another affects
+  both name resolution and legality. With the refined definition of
+  "descendant," whether a given class-wide type covers a particular
+  type depends on the visibility of the chain of derivation to the
+  parent type.
+
+  In 12.5.1(5.1/3), an actual type for a formal derived type is required
+  to be a descendant of the specified ancestor type and of the specified
+  progenitors. The refined definition of "descendant" requires that the
+  chain of derivation be visible to the view of the parent of the actual
+  type from which the current view of the actual type is derived. If at
+  the point of the instantiation, more is visible than at the point
+  where this view of the parent type was declared, no use of that
+  information may be made in determining legality.
+
+One could argue that these cases are potential sources of
+incompatibility. An alternative approach would be to say that a type is
+considered a descendant of a type at any place where the entire chain of
+derivation is visible. But it *inherits* characteristics only from
+ancestors from which its parent inherits characteristics. Convertibility
+and matching/covering/etc. would be an exception. Effectively a type
+can be a descendant of what we might call the "incomplete" view of some
+ancestor. No characteristics come from it, other than the ability to
+convert (explicitly or implicitly due to being "covered") or to pass as
+an actual in a generic instantiation.
+
+See the !example section below for more detailed discussion of how this
+"refined" definition of ancestor relates to the original question,
+namely the legality of various aggregates.
+
 ---
 
 We added a separate rule about ancestors with unknown discriminants. It is
@@ -2207,6 +2275,15 @@
 
 ****************************************************************
 
+From: Tucker Taft
+Sent: Thursday, March 17, 2011  9:07 AM
+
+I did a preliminary review and didn't find any problems, other than your
+run-time issue in Ada.Tags.  I just didn't have time to do a formal writeup of
+each occurrence.
+
+****************************************************************
+
 From: Edmond Schonberg
 Sent: Sunday, March 20, 2011   9:00 AM
 
@@ -2283,5 +2360,140 @@
 
 Please make sure that you report this to the ACAA Technical Agent so I can put
 it on the pile of ACATS tests needing fixes for Ada 2012.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, March 31, 2011  10:50 PM
+
+[Attached to version /07 of the AI.]
+
+I have added to the discussion here the results of scanning the standard for
+uses of "descendant," "descended from," "ancestor," "covers," etc.
+
+The implications are that there are various places where the "ancestry" of a
+type affects legality and overload resolution.  I believe we want to stick with
+the basic rule that essentially all "characteristics" are inherited "through"
+the immediate parent, and if a derived type happens to know more than its parent
+type about its ancestry, it can't use that information, for example, to refer to
+a component that its parent couldn't see.
+
+However, when it comes to things like type conversion, generic instantiation as
+an actual for a formal derived type, "coverage" by a class-wide type, etc., I
+could imagine having a more flexible rule.  That is, if a type knows it is
+derived indirectly from some type, even though its parent type does *not* know
+that fact, it can at a minimum be convertible to that "secret" ancestor.
+
+I didn't write the wording that way, but we might want to consider it.  One way
+I imagined doing that was saying that in cases like that, the child type is
+essentially a descendant of an "incomplete" view of the ancestor. It inherits no
+characteristics from that ancestor, other than the right to be converted to it,
+or to match it for the purposes of formal derived types, or things like that
+('Class coverage, etc.). I have some suspicion that this approach would be more
+compatible with what most compilers do today, and it doesn't seem to cause any
+trouble.  This is in contrast to inheriting characteristics from such a secret
+ancestor, as you could get into real trouble if you could see a component of a
+secret ancestor that had the same name as a component of your parent type
+(unbeknownst to the parent type).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, April  1, 2011  12:35 AM
+
+> I have added to the discussion here the results of scanning the
+> standard for uses of "descendant,"
+> "descended from," "ancestor," "covers," etc.
+
+Thanks for doing this analysis. It went far beyond what I was contemplating
+(although it appears to have been necessary).
+
+> The implications are that there are various places where the
+> "ancestry" of a type affects legality and overload resolution.  I
+> believe we want to stick with the basic rule that essentially all
+> "characteristics" are inherited "through" the immediate parent, and if
+> a derived type happens to know more than its parent type about its
+> ancestry, it can't use that information, for example, to refer to a
+> component that its parent couldn't see.
+>
+> However, when it comes to things like type conversion, generic
+> instantiation as an actual for a formal derived type, "coverage" by a
+> class-wide type, etc., I could imagine having a more flexible rule.
+> That is, if a type knows it is derived indirectly from some type, even
+> though its parent type does
+> *not* know that fact, it can at a minimum be convertible to that
+> "secret" ancestor.
+
+I think this shows that I was right that there are far-reaching effects.
+
+> I didn't write the wording that way, but we might want to consider it.
+> One way I imagined doing that was saying that in cases like that, the
+> child type is essentially a descendant of an "incomplete" view of the
+> ancestor.
+> It inherits no characteristics from that ancestor, other than the
+> right to be converted to it, or to match it for the purposes of formal
+> derived types, or things like that ('Class coverage, etc.).
+> I have some suspicion that this approach would be more compatible with
+> what most compilers do today, and it doesn't seem to cause any
+> trouble.  This is in contrast to inheriting characteristics from such
+> a secret ancestor, as you could get into real trouble if you could see
+> a component of a secret ancestor that had the same name as a component
+> of your parent type (unbeknownst to the parent type).
+
+My immediate, unverified thought is that the rules you currently have could do
+some real harm to the implementation of Claw and its tools (although I couldn't
+know for sure without having a compiler that strictly implemented the rules).
+Conversions to Root_Window_Type'Class are quite common, and if there is a type
+for which that ancestry isn't "visible", we'd have trouble. Similarly for
+Root_Dialog_Type'Class. I realize that there would always be a chain of
+conversions that would be legal, but that would be ugly.
+
+Let me write a quick example of what you are talking about to see if I
+understand properly.
+
+   package P1 is
+      type Root is abstract tagged ...;
+      procedure Draw (W : Root'Class);
+   end P1;
+
+   package P1.P2 is
+      type Subroot is abstract private;
+      procedure Paint (W : Subroot'Class);
+   private
+      type Subroot is new Root with ...;
+   end P1.P2;
+
+   package P1.P2.P3 is
+      type A_Win is new Root with private;
+   private
+      type A_Win is new Subroot with ...
+   end P1.P2.P3;
+
+   with P1.P2.P3;
+   package P1.P2.P4 is
+      type B_Win is new A_Win with ...;
+      procedure Test (W : B_Win);
+   end P1.P2.P4;
+
+   with P1.P2.P4;
+   procedure Unrelated is
+      W : P1.P2.P4.B_Win;
+   begin
+      P1.Draw (W); -- Legal (?)
+      P1.P2.Paint (W); -- Illegal (?)
+   end Unrelated;
+
+   package body P1.P2.P4 is
+      procedure Test (W : B_Win) is
+      begin
+          P1.Draw (W); -- Legal.
+          P1.Draw (A_Win(W)); -- Legal.
+          P1.P2.Draw (W); -- Illegal.
+          P1.P2.Draw (A_Win(W)); -- Legal.
+      end Test;
+   end P1.P2.P4;
+
+Humm, I don't seem to have managed to create the situation you are worried
+about. Could you show an example??
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent