CVS difference for ais/ai-00326.txt

Differences between 1.9 and version 1.10
Log of other versions for file ais/ai-00326.txt

--- ais/ai-00326.txt	2004/01/23 04:59:28	1.9
+++ ais/ai-00326.txt	2004/03/03 00:21:34	1.10
@@ -1054,3 +1054,454 @@
 
 *************************************************************
 
+From: Pascal Leroy
+Sent: Friday, February 27, 2004,  6:59 AM
+
+One of my actions items from the San Diego meeting reads: "Check that
+the current wording of AI-326 properly handles all of the examples
+discussed in previous meetings for AI-217."
+
+I have done this analysis and I am attaching a document that reviews all
+these examples (some of them were based on ancient alternatives of AI
+217, so I had to adapt them to the "limited with" model).
+
+Bad news: the last examples from the Cupertino and Toulouse meetings
+demonstrate that we have reintroduced ripple effects.  In essence,
+whenever we say "a dereference which is of an incomplete view is illegal
+if so-and-so" there is a ripple effect, because changing a "limited
+with" to a "with" (or vice-versa) at the place where the access type is
+declared can cause legality changes in distant places.
+
+Not sure how to fix this...
+
+-------- Cupertino
+
+package P is
+private
+    type T is tagged;
+    procedure Print (X : T);
+    type T_Ptr is access all T;
+end P;
+
+private procedure P.Proc (Y : T_Ptr);
+
+procedure P.Proc (Y : T_Ptr) is
+    Print (Y.all); -- Legal? (Yes.)
+end P.Proc;
+
+This example is legal because Y.all is of the incomplete view of T
+(3.10.1(11)), and the type of the formal parameter of Print is also the
+incomplete view of T, so the two match.  Furthermore the defereference Y.all is
+not a prefix, so it is legal (3.10.1(10)).
+
+
+private procedure P.Proc2 (Y, Z : T_Ptr);
+
+procedure P.Proc2 (Y, Z : T_Ptr) is
+begin
+    Z.all := Y.all; -- Legal? (No.)
+end P.Proc2;
+
+This example is illegal because Z.all and Y.all are both of the incomplete view
+of T, and an incomplete view is a limited view (3.10.1(11)).
+
+
+package Q is
+    type T is tagged ...;
+end Q;
+
+with Q;
+package R is
+    A : Q.T;
+end R;
+
+limited with Q;
+with R;
+procedure Proc3 (Y : access Q.T) is
+    W : Q.T renames Y.all; -- Legal? (No.)
+begin
+    R.A := Y.all; -- Legal? (Yes.)
+end Proc3;
+
+The renaming is illegal, because Q.T is the incomplete view, and an incomplete
+view is not permitted as the type of a renaming.
+
+The assignment is legal.  R.A is of the full view of T, so it is not limited.
+The expected type of Y.all is T, and this expression is actually of the
+incomplete view of T, so name resolution works fine.
+
+
+with Q;
+package R2 is
+    A : Q.T;
+    procedure Store (I : out Q.T; J : P.T);
+end R2;
+
+limited with Q;
+with R2;
+procedure Proc4 (Y, Z : access Q.T) is
+begin
+    R2.Store (Z.all, Y.all); -- Legal? (Yes.)
+end Proc4;
+
+This example is legal, because Y.all and Z.all are of the incomplete view of T,
+and in the call they are expected to be of type T, so name resolution works
+fine.
+
+
+limited with Q;
+package R3 is
+    type T2_Ptr is access Q.T;
+end R3;
+
+with R3;
+procedure Proc5 is
+    A, B : R3.T2_Ptr;
+begin
+    A.all := B.all; -- Legal? (RIPPLE EFFECT HERE!)
+end Proc5;
+
+As written, the example is illegal because A.all and B.all are of the
+incomplete view of T, which is limited.  However, if the "limited with Q" in R3
+is changed to "with Q", A.all and B.all become nonlimited and the example
+becomes legal.
+
+
+-------- Vienna
+
+package Q is
+    type T is tagged ...
+end Q;
+
+limited with Q;
+package R is
+    type A is access T'Class;
+    O : A;
+end R;
+
+with Q, R;
+package P is
+    OC : Q.T;
+begin
+    OC := R.O.all; -- Legal? (Yes.)
+end P;
+
+The type of OC is the full view of T.  The type of R.O.all is the full view of
+T'Class because of the presence of the "with Q".  The expected type of R.O.all
+is the full view of T, so the assignment is legal according to 8.6(23).
+
+
+type T is tagged;
+type A is access T;
+O : A;
+type T (D : Integer) is tagged ...;
+... A.all.D ... -- Legal? (Yes.)
+
+In this example A.all occurs within the immediate scope of the completion of T,
+so it is of the full view of T, and therefore its use as a prefix is legal (and
+the discriminant D is visible).
+
+
+-------- Padua
+
+package Q is
+    type T is ...;
+    Z : T;
+end Q;
+
+limited with Q;
+package P is
+    type Acc is access Q.T;
+    X : Acc;
+end P;
+
+with Q;
+package A is
+    package MyQ renames Q;
+end A;
+
+with P; with A;
+package R is
+    ... P.X.all ... -- Legal? (Depends.)
+end R;
+
+P.X.all is of an incomplete type.  It is not legal if used as a prefix or as
+the left-hand side of an assignment, but other uses are acceptable.  At any
+rate, the legality of the dereference does not depend on the "with Q" in A.
+
+
+limited with Q;
+with P, A;
+package R2 is
+    ... P.X.all ... -- Legal? (As above.)
+    ... A.MyQ.Z ... -- Legal? (Yes.)
+    ... Q.Z ... -- Legal? (No.)
+end R2;
+
+The legality of P.X.all is as in the example above.  A.MyQ.Z is legal through
+the normal visibility rules.  Q.Z is illegal because the full view of Q is
+hidden from all visibility within the scope of the "limited with Q", regardless
+of the presence of MyQ in A.
+
+with Q;
+package QE2 renames Q;
+
+with QE2;
+limited with Q; -- Illegal.
+with P, A;
+package R3 is
+    ... P.X.all ... -- Legal? (Irrelevant.)
+    ... QE2.Z ... -- Legal? (Irrelevant.)
+    ... Q.Z ... -- Legal? (Irrelevant.)
+end R3;
+
+In this case the "limited with Q" is illegal because it occurs in the same
+context_clause as a nonlimited_with_clause which mentions the same library_item
+(the "with QE2" mentions Q).
+
+
+-------- Toulouse
+
+package Q is
+    type T is ...;
+    procedure Proc (Param : T);
+    X : T;
+end Q;
+
+with Q;
+package P is
+    package R renames Q;
+end P;
+
+with P;
+limited with Q;
+package PP is
+    Obj1 : Q.T; -- Legal? (No.)
+    Obj2 : P.R.T; -- Legal? (No.)
+end PP;
+
+The first declaration is illegal because Q.T is the incomplete view of T, and
+an object_declaration is not a legal use for an incomplete view.  The second
+declaration is illegal because, within the scope of the "limited with Q", the
+full view of Q is hidden from all visibility.  Therefore, P.R.T is the
+incomplete view of T, and it cannot be used in an object declaration.
+
+
+with Q;
+package R1 is
+    subtype Foo is Q.T;
+    type Rec is private;
+    Z : Q.T;
+    function "=" (A, B : Q.T) return Boolean renames Q."=";
+private
+    type Rec is
+        record
+            F : Q.T;
+        end record;
+end R1;
+
+with R1;
+limited with Q;
+package S1 is
+    X : R1.Rec; -- Legal? (Yes.)
+    Y : Q.T; -- Legal? (No.)
+    Z : R1.Foo; -- Legal? (Yes.)
+    Maybe : Boolean := R."=" (R1.Z, X.F); -- Legal? (Would be if F were visible.)
+end S1;
+
+The declaration of X is trivially legal: even though the full view of Q is
+hidden from all visibility, there is no reference to that view in the
+declaration of X.  The declaration of Y is illegal precisely because the full
+view of Q is hidden from all visibility.  The declaration of Z is legal for
+essentially the same reason as that of X.  And the call to "=" in the
+declaration of Maybe would be legal if the component F were visible, because
+again there is no name resolution involving a view of Q.
+
+
+package Q3 is
+    type T is tagged
+        record
+            Comp : Natural;
+        end record;
+    procedure Proc (Param : T);
+    X : T;
+end Q3;
+
+limited with Q3; -- (0)
+package P3 is
+    type Acc_Inc is access Q3.T;
+    X : Acc_Inc;
+end P3;
+
+with Q3; -- (1)
+package R3 is
+    M : Q3.T := P3.X.all; -- Legal? (Yes.)
+    procedure Proc (X : Q3.T);
+end R3;
+
+with P3, R3;
+procedure S3 is
+    N : Natural := P3.X.all.Comp; -- Legal? (RIPPLE EFFECT.)
+begin
+    R3.Proc (P3.X.all); -- Legal? (Yes.)
+end S3;
+
+The dereference P3.X.all in the declaration of M is legal: P3.X.all is of the
+incomplete view of Q3.T, and its expected type is the full view of Q3.T, so the
+two match.  If the with_clause marked (1) were changed to a
+limited_with_clause, the declaration of M would become illegal because Q3.T
+would be a limited type.
+
+The dereference P3.X.all.Comp in the declaration of N is illegal because
+P3.X.all is of the incomplete view of Q3.T, so it cannot be used as a prefix.
+However, if the with_clause marked (0) were changed to a
+nonlimited_with_clause, the declaration of N would become legal.  YARE!  (Yet
+Another Ripple Effect.)
+
+The call to R3.Proc is legal because P3.X.all is of the incomplete view of T,
+and its expected type is T.  Note that this is true even if the with_clause
+marked (1) is changed to a limited_with_clause (that's necessary to prevent
+ripple effects).
+
+
+-------- Sydney
+
+limited with Depts;
+package Emps is
+    type Employee is private;
+    procedure Assign (E : Employee; D : Depts.Department);
+    type Dept_Ptr is access Depts.Department;
+end Emps;
+
+with Emps;
+procedure Recruit (D : Emps.Dept_Ptr; E : Emps.Employee) is
+begin
+    Emps.Assign (E, D.all); -- Legal? (Yes.)
+end Recruit;
+
+Here D.all is of the incomplete view of Depts.Department, and its expected type
+is the incomplete view of Depts.Department, so the two match and the call is
+legal.
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Friday, February 27, 2004,  7:35 PM
+
+OK. Let's start with the easy stuff:
+
+--- Cupertino:
+
+with Q;
+package R2 is
+    A : Q.T;
+    procedure Store (I : out Q.T; J : P.T);
+end R2;
+
+There's no P visible here. I think that is supposed to be Q.T, not P.T.
+
+--- Toulouse:
+
+with R1;
+limited with Q;
+package S1 is
+    X : R1.Rec; -- Legal? (Yes.)
+    Y : Q.T; -- Legal? (No.)
+    Z : R1.Foo; -- Legal? (Yes.)
+    Maybe : Boolean := R."=" (R1.Z, X.F); -- Legal? (Would be if F were visible.)
+end S1;
+
+There's no R visible here. I think that is supposed to be R1."=".
+
+---
+
+Now, the not so easy stuff:
+
+> Bad news: the last examples from the Cupertino and Toulouse meetings
+> demonstrate that we have reintroduced ripple effects.  In essence,
+> whenever we say "a dereference which is of an incomplete view is illegal
+> if so-and-so" there is a ripple effect, because changing a "limited
+> with" to a "with" (or vice-versa) at the place where the access type is
+> declared can cause legality changes in distant places.
+
+I'm not sure that this is a problem that could be solved without making "limited with" useless. It's hard to imagine any other result. Let me explain. Here's the example that causes trouble:
+
+limited with Q; -- or with Q;
+package R3 is
+    type T2_Ptr is access Q.T;
+end R3;
+
+with R3;
+procedure Proc5 is
+    A, B : R3.T2_Ptr;
+begin
+    A.all := B.all; -- Legal? (No was written, Yes if "with Q") - RIPPLE EFFECT HERE!
+end Proc5;
+
+Changing "with Q" to "limited with Q" essentially is changing the declaration
+of the type Q.T from a complete tagged type to an incomplete type. It cannot be
+surprising that changing a declaration causes changes in the legality
+elsewhere. Certainly if you made such a change explicitly in the program text,
+you'd expect there to be a recompile/recheck. (Think of changing a visible
+non-limited type to a private limited type. Would you be surprised? Thought
+not.) There are many examples of this sort of "ripple effect" in Ada, so I
+don't think this is a problem.
+
+In any case, changing from limited with to with only makes illegal code legal.
+That's hardly a problem in practice (who has thousands of lines of illegal code
+sitting around waiting for a change somewhere to make it legal??). Changing in
+the other direction is obviously dangerous and rarely necessary (only if the
+design needs major changes); you're removing a lot of capability, and no one
+should be surprised if that makes code illegal. Such changes need to be avoided
+anyway - hopefully Ada programming guides will make this clear.
+
+This doesn't seem to be a huge implementation problem, either. Changing limited
+with <-> with is essentially the same as any other significant edit to a spec.
+-- it requires rechecking all dependent units. If you need specific entities to
+change, you'd have to scan the spec. and mark all of the entities that depend
+on the withed package (Q) as changed, so that they're rechecked.
+
+Note that this cannot happen unless the with clause is "needed"; that is that
+it is referenced somewhere in the spec. of the package (or its children). So,
+this can't happen by the adding or removing of otherwise unneeded with clauses
+-- which is the maintenance problem that we wish to avoid by avoiding ripple
+effects. (If the with clause was totally removed, you'd get a local error -
+which is not a ripple effect.)
+
+The Toulouse example is precisely the same effect (changing a declaration of a
+"needed" item).
+
+The only way that this could be fixed would be to insure that precisely the
+same properties exist for a type whether it is complete or incomplete. (That
+is, avoid the possibility of a legality change.) But that way lies madness -
+either massive incompatibility (by removing capabilities from full types) or
+it's unimplementable (because we'd be accessing things not yet defined!).
+
+So, I don't think that there is a problem worth fixing (or able to fix, for
+that matter) here. This is a very mild ripple effect (if it is one at all; I
+wasn't able to find a definition of the term in a quick search).
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, March 2, 2004,  4:14 AM
+
+After giving it more thought, I agree with your analysis.  In fact, I
+think it would fall out naturally from our incremental compilation
+mechanism.
+
+It might also be good to add to the !discussion section of the
+AI an example of this pseudo-ripple effect, together with an explanation
+of why this is not really problematic.
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, March 2, 2004,  5:58 PM
+
+I don't think this issue has much to do with 326; it's really all about
+"limited with" (not incomplete types per-se). So any change should be in
+that AI.
+
+*************************************************************
+

Questions? Ask the ACAA Technical Agent