CVS difference for ais/ai-00326.txt

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

--- ais/ai-00326.txt	2003/07/15 20:41:55	1.2
+++ ais/ai-00326.txt	2003/07/26 03:26:02	1.3
@@ -323,3 +323,211 @@
 
 *************************************************************
 
+From: Tucker Taft
+Sent: Tuesday, July 15, 2003  2:46 PM
+
+I would suggest we keep it as simple as possible.
+If at some later point we think we can open it up
+more, that is possible, but a really complex rule
+probably doesn't help anyone at this point.
+
+I like your suggestion of allowing class-wide incomplete types only,
+and disallow any calls with parameters of a non-class-wide
+incomplete type.  That seems pretty simple to define and
+enforce.  I suppose we need to worry about S'Class, where
+subtype S is T(discrim => value).  It seems the prefix of the
+Class attribute must be the first subtype.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, July 15, 2003  8:28 PM
+
+Tucker Taft wrote:
+
+...
+>I like your suggestion of allowing class-wide incomplete types only,
+>and disallow any calls with parameters of a non-class-wide
+>incomplete type.
+
+Sounds reasonable.
+
+>                  That seems pretty simple to define and
+>enforce.  I suppose we need to worry about S'Class, where
+>subtype S is T(discrim => value).  It seems the prefix of the
+>Class attribute must be the first subtype.
+
+This sent me scurrying off to the AARM, which was perfectly unclear:
+
+3.9 (15) S'Class is unconstrained. However, if S is constrained, then
+the values of S'Class are only those that when converted to the type T
+belong to S.
+
+3.9(15b) Note that if S is constrained, S'Class is only partially
+constrained, since there might be additional discriminants added in
+descendants of T which are not constrained.
+
+In any case, I don't see that your proposed restriction buys anything. I
+think you are trying to avoid cases where there is a subtype that is
+more constrained than the base class. But in theory I could restructure
+things so that S was a first subtype with the same discriminant
+constraints. So as long as S'Class is allowed where S is a derived type,
+I don't see the limitation accomplishing anything other than confusing
+Ada programmers. In any case, since the (class-wide) name must appear in
+a context where it is going to be resolved by run-time dispatching, any
+freezing issues are long gone.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, July 15, 2003  2:46 PM
+
+It is important we don't allow "partially" constrained
+subtypes of an incomplete type as actuals, since the
+caller doesn't know where the discriminants are.
+However, perhaps we are safe, since named subtypes
+of incomplete types aren't allowed, so it would not
+be possible to declare a named subtype S, and hence
+there would be no way to write a partially constrained
+(incomplete class-wide) subtype S'Class.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Wednesday, July 16, 2003  11:38 AM
+
+Tucker Taft wrote:
+
+> It is important we don't allow "partially" constrained
+> subtypes of an incomplete type as actuals, since the
+> caller doesn't know where the discriminants are.
+> However, perhaps we are safe, since named subtypes
+> of incomplete types aren't allowed, so it would not
+> be possible to declare a named subtype S, and hence
+> there would be no way to write a partially constrained
+> (incomplete class-wide) subtype S'Class.
+>
+
+But the caller may also be passing an object of a type (not subtype)
+that is totally unknown where the call is made.  That is the nature of
+calls with class-wide formals.  Let me give an example of the full
+horror, and you will see that compilers SHOULD be handling it correctly now:
+
+package P is
+    type T(Some: Discriminants)  is tagged....;
+    subtype S is T(This_Discriminant);
+    function Some_Function(SP: S) return Integer;
+end P;
+
+with P; use P;
+package U is
+    procedure Some_Proc(TC: in T'Class);
+end U;
+
+package body U is
+    procedure Some_Proc(TC: in T'Class) is
+        I:  Integer := Some_Function(TC);  -- discriminant check is here...
+    begin null; end;
+end U;
+
+package Q is
+    type R is new T with private;
+private
+    ...
+end Q;
+
+with P, Q, U; use P, Q, U;
+procedure Main is
+    QR: R;
+begin
+    Some_Proc(QR);
+end Main;
+
+I think that gets it.  The discriminant check on the call to
+Some_Function has to be made by code that doesn't even know that type R
+will exist.  I don't know how current compilers handle this, I have been
+assuming that if they let users control the layout of discriminants in
+derived types that the dispatch table includes a thunk for finding
+discriminants.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Wednesday, July 16, 2003  12:02 PM
+
+I think I just misspoke in my example, but it doesn't change the issue.
+The discriminant check occurs after a view conversion to the subtype of
+the formal parameter, but the function I used in my example is illlegal
+where it is declared. (The legality rule in 3.9.2(10/1) prevents it.) So
+change the example to:
+
+package P is
+type T(Some: Discriminants) is tagged....;
+subtype S is T(This_Discriminant);
+function Some_Function(SP: S'Class) return Integer;
+-- or worse
+function Some_Other_Function(SP: S'Class) return T;
+-- now it is dispatching, but the parameter with the subtype check is
+classwide.
+end P;
+
+with P; use P;
+package U is
+procedure Some_Proc(TC: in T'Class);
+end U;
+
+package body U is
+procedure Some_Proc(TC: in T'Class) is
+I: Integer := Some_Function(TC); -- discriminant check is here...
+begin null; end;
+end U;
+
+package Q is
+type R is new T with private;
+private
+...
+end Q;
+
+with P, Q, U; use P, Q, U;
+procedure Main is
+QR: R;
+begin
+Some_Proc(QR);
+end Main;
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, July 23, 2003  6:53 PM
+
+Robert Eachus wrote:
+
+..
+> I think that gets it.  The discriminant check on the call to
+> Some_Function has to be made by code that doesn't even know that type R
+> will exist.  I don't know how current compilers handle this, I have been
+> assuming that if they let users control the layout of discriminants in
+> derived types that the dispatch table includes a thunk for finding
+> discriminants.
+
+13.5.1(14) says that the layout of a parent part (obviously including the
+discriminants) can't be changed by a record rep. clause. Note that this is a
+RULE, not a "recommended level of support" -- compilers are not allowed to
+change the layout of the parent part. So there is no problem here.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Thursday, July 24, 2003  5:44 PM
+
+The intent in my example was to have a call on the parent type have to
+perform a discriminant check necessary because of a subtype of the child
+type.
+
+But I see that Randy is right.   A derived type can add a variant part,
+but it has to depend on an existing discriminant.  So as far as the
+compiler is concerned there is no difference between a subtype of a
+derived (tagged) type and a subtype of the parent.
+
+*************************************************************
+

Questions? Ask the ACAA Technical Agent