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

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

--- ai05s/ai05-0115-1.txt	2011/04/02 07:30:35	1.12
+++ ai05s/ai05-0115-1.txt	2011/04/22 03:01:40	1.13
@@ -1,4 +1,4 @@
-!standard 4.3.2(5/2)                                  11-03-30  AI05-0115-1/07
+!standard 4.3.2(5/2)                                  11-04-19  AI05-0115-1/08
 !standard 7.3.1(5/1)
 !class binding interpretation 08-10-15
 !status work item 08-10-15
@@ -17,6 +17,11 @@
 not have unknown discriminants if the ancestor part is specified with a
 subtype_mark.
 
+Type conversion, type coverage, formal derived type matching, etc.,
+is permitted any place where the chain of derivations connecting the
+two types is visible, even if one of the ancestors in the chain
+might not have visibility on all of the intermediate derivations.
+
 !question
 
 Consider the following:
@@ -136,7 +141,38 @@
   a descendant of a record type, or a descendant only through record
   extensions of some more distant ancestor].
 
+  [Redundant:  It is possible for there to be places where a derived
+  type is visibly a /descendant/ of an ancestor type, but not a
+  descendant of even a partial view of the ancestor type, because the parent
+  of the derived type is not visibly a descendant of the ancestor.  In
+  this case, the derived type inherits no characteristics from that
+  ancestor, but nevertheless is within the derivation class of the
+  ancestor for the purposes of type conversion, the "covers"
+  relationship, and matching against a formal derived type.  In this
+  case the derived type is considered to be a /descendant/ of an
+  incomplete view of the ancestor.]
+
+  [AARM Discussion:  Here is an example of this situation:
+     package P is
+        type T is private;
+     private
+        type T is new Integer;
+     end P;
+
+     with P;
+     package Q is
+         type T2 is new T;
+     end Q;
 
+     package P.Child is
+         type T3 is new T2;
+     private
+         X : T3 := T3(42);  -- legal: conversion allowed
+         Y : T3 := X + 1;   -- error: no visible "+" operator
+     end P.Child;
+
+   ]
+
 !discussion
 
 Logically, an aggregate is a shorthand for setting each component individually.
@@ -168,62 +204,68 @@
 
 Here we take the approach of defining the view of an ancestor from which
 a given view of a type is a descendant.  The basic principle is that you
-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.
+inherit characteristics from an ancestor only through your immediate parent
+type, and you can never end up with "more" characteristics than that of your
+parent type.  However, we have preserved the ability to convert to any visible
+ancestor, even if the parent is unaware of the ancestor.
+
+The reference manual was scanned to see whether to extend the notion of
+"descendant of a view" to the more general definition of "descendant."
+It was decided to preserve the most "generous" definition of descendant,
+while disallowing inheriting any characteristics if the full chain of
+derivation was not visible to the parent type. When no characteristics
+are inherited from an ancestor, we consider the derived type to be a
+descendant of an incomplete view of the ancestor. 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 does to some extent.
 
-To be precise about where this change has effects:
+To be precise about where a change to the general definition of
+"descendant" would have had significant 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
+  terms of type derivation and/or descendant. In all cases, an altered
   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
+  "ancestor" and "descended from." With an altered 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
+  but which its immediate parent cannot see. Such a change would 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
+  both name resolution and legality. With an altered definition of
   "descendant," whether a given class-wide type covers a particular
-  type depends on the visibility of the chain of derivation to the
+  type would depend 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
+  progenitors. An altered definition of "descendant" would require 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.
+  information could 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.
+We worried that an altered definition of descendant might create
+incompatibilities, and there seemed no definition concern with allowing
+conversions, matching, etc., to be as generous as possible. So long as
+it *inherits* characteristics only from ancestors from which its parent
+inherits characteristics, we felt there would be no problem. 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,
+view-related definition of ancestor relates to the original question,
 namely the legality of various aggregates.
 
 ---
@@ -2501,28 +2543,28 @@
 From: Jean-Pierre Rosen
 Sent: Friday, April  1, 2011  2:28 AM
 
-> 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 
+> 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.
 
 But then, you could access the secret components after converting to the
 secret ancestor (just a note, I don't know whether it's good or bad)
 
-> 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 
+> 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 
+> 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 
+> 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).
 
 And after conversion, there is no ambiguity since new homonym components
@@ -2533,7 +2575,7 @@
 From: Tucker Taft
 Sent: Friday, April  1, 2011  10:49 AM
 
-> Humm, I don't seem to have managed to create the situation you are 
+> Humm, I don't seem to have managed to create the situation you are
 > worried about. Could you show an example??
 
 Something like this:
@@ -2578,22 +2620,22 @@
 
 I see. I don't think we ever do this in Claw, so now I'm less worried.
 
-> I don't know that I am "worried" about this in the abstract, but I am 
-> concerned if there is a chunk of existing code that will break due to 
+> I don't know that I am "worried" about this in the abstract, but I am
+> concerned if there is a chunk of existing code that will break due to
 > such a "refinement" of the definition.
 
 Right.
 
-> Ed reported that he didn't see any significant problems in the AdaCore 
-> regression test suite, but that may have only been with the 
-> instantiation situation where an actual type was a "secret" descendant 
+> Ed reported that he didn't see any significant problems in the AdaCore
+> regression test suite, but that may have only been with the
+> instantiation situation where an actual type was a "secret" descendant
 > of the formal derived type ancestor.
-> 
-> In any case I think we definitely want to say that as far as 
-> inheriting subprograms, components, ability to write aggregates, etc., 
-> we stick with the "refined" model.  The only open question in my mind 
-> is this issue of conversion/matching, as it seems like a useful 
-> work-around for a programmer in certain situations where the 
+>
+> In any case I think we definitely want to say that as far as
+> inheriting subprograms, components, ability to write aggregates, etc.,
+> we stick with the "refined" model.  The only open question in my mind
+> is this issue of conversion/matching, as it seems like a useful
+> work-around for a programmer in certain situations where the
 > inheritance chain is "interrupted."
 
 Right. It seems nasty to say that you can't convert to a type that you can see.
@@ -2605,5 +2647,19 @@
 
 I know I did this occasionally in the Claw builder code, but I think it was
 caused by more straightforward "invisibilities".
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, April 19, 2011  3:44 PM
+
+Here is a significant update to AI-0115 on the notion of being a descendant of a
+particular "view" of an ancestor.  We decided to be very generous when it comes
+to conversion, formal derived type matching, etc., while being very restrictive
+as far as inheriting characteristics from an ancestor.  You only inherit
+characteristics via the immediate parent -- no generation skipping. But you have
+the right to convert to any ancestor you know about.
+
+[This is version /08 of the AI - Editor.]
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent