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

Differences between 1.7 and version 1.8
Log of other versions for file ai05s/ai05-0123-1.txt

--- ai05s/ai05-0123-1.txt	2009/03/21 03:43:37	1.7
+++ ai05s/ai05-0123-1.txt	2009/04/14 18:38:09	1.8
@@ -1,4 +1,4 @@
-!standard  4.5.2(10-26)                                        09-03-20    AI05-0123-1/04
+!standard  4.5.2(10-26)                                        09-04-07    AI05-0123-1/05
 !class Amendment 08-10-17
 !status work item 08-10-17
 !status received 08-09-03
@@ -70,15 +70,11 @@
 These cases are dealt with as follows:
 
    1) The "composed" equality operator for a type with a component
-      whose primitive "=" operator is abstract is also abstract.
-      In the case of a nonabstract tagged type, this operator would
-      have to be overridden just like any other abstract operation
-      (ditto in the case of a nonabstract extension of a parent type
-      which has an abstract "=" operator).
-      A type with an abstract "=" operator cannot be passed as
-      a generic actual corresponding to a formal private or formal
-      derived type (except in the case of a formal derived type which
-      also has an abstract "=" operator).
+      whose primitive "=" operator is abstract is defined to raise
+      Program_Error at the point where the abstract function would
+      otherwise have been called. Similarly for the predefined equality
+      operator for an untagged record type whose primitive "=" operator
+      is abstract.
    2) A user-defined primitive "=" operator for an untagged record type
       may not be declared after the freezing point of the type,
       nor may it be declared in the private part of a package
@@ -105,48 +101,23 @@
 
 !wording
 
-Append after 4.5.2(9) (i.e., at the end of the Static Semantics section)
+In 4.5.2, move the Legality Rules section from just ahead of the
+Static Semantics section to just after and then append at the end
+of the Legality Rules section:
 
-  The predefined equality operator for a nonlimited composite type
-  is abstract if any one of the type's noninherited component types
-  is a record or private type (tagged or untagged) whose primitive
-  equality operator is abstract or an array type whose predefined equality
-  operator is abstract. In the case of a nonabstract tagged type,
-  this abstract operator requires overriding.
-
-
-Move the Legality Rules section from just ahead of the Static Semantics
-section to just after and then append at the end of the Legality
-Rules section:
-
-  If the predefined equality operator for an array type
-  is abstract, or if the primitive equality operator for an untagged
-  record or untagged private type is abstract, then:
-    - the type shall not be used as a component type of an enclosing
-      type which is neither tagged nor immutably limited (see 7.5);
-    - the type shall not be passed as actual parameter to an
-      instantiation if the corresponding formal type is nonlimited
-    - the type shall not be passed as actual parameter to an
-      instantiation if the corresponding formal type is a
-      formal derived type which is not immutably limited;
-    - the type shall not be the completion of a nonlimited partial view. 
-
   The explicit declaration of a primitive equality operator of an
   untagged record type shall occur before the type is frozen.
   If the untagged record type has a nonlimited partial view, then the
   declaration shall occur in the visible part of the enclosing package.
+  In addition to the places where Legality Rules normally apply (see 12.3),
+  this rule applies also in the private part of an instance of a generic unit.
 
   AARM Note:
   The phrase "equality operator" as used here refers only to a
   function whose profile is type conformant with that of the
   predefined equality operator for the untagged record type.
-  End AARM Note.
-
-  In addition to the places where Legality Rules normally apply (see 12.3),
-  these rules apply also in the private part of an instance of a generic unit.
 
 
-
 In 4.5.2(14), replace
 
   For a type extension, predefined equality is defined in terms of the
@@ -160,7 +131,7 @@
   primitive [(possibly user-defined)] equals operator of the parent type
   and of any record components (tagged or untagged) of the extension part,
   and predefined equality for any other components not inherited from the
-  parent type. 
+  parent type.
 
 
 In 4.5.2(15), replace 
@@ -190,6 +161,18 @@
   for any matching record components (tagged or untagged), and the predefined
   equals for any other matching components.
 
+  If the primitive equals operator for an untagged record type is abstract,
+  then Program_Error is raised at the point of any (implicit)
+  call to that abstract subprogram.
+
+  AARM Note:
+  An explicit call to an abstract subprogram is illegal.
+  This rule is needed in order to define the effect of an
+  implicit call such as a call that is part of the
+  predefined equality operation for an enclosing composite type
+  that has a component of an untagged record type that has an
+  abstract primitive equals operator.
+
 
 In 32.a.1/1, replace
   "then either the full type must be tagged"
@@ -215,132 +198,43 @@
 and some (hopefully unimportant) incompatibilities are introduced.
 
 ----
-
-An array type may end up with an abstract predefined "=" operator
-(and "/=" operator, for that matter) if the element type has
-this property. Such an array type must not be passed as an actual
-to a generic with a formal array type which expects non-abstract
-equality operators. This was not previously discussed in the AI.
-
-----
-
-The restriction on the use of abstract-"=" types as components
-stems from a desire to avoid scenarios such as the following:
-  package Pkg is
-    type Rec is null record;
-    function "=" (L, R) return Boolean is abstract;
-
-    type Drec is new Rec; -- inherits abstract "="
-
-    type Vec is array (Boolean) of Drec;
-
-    function "=" (L, R : Drec) return Boolean;
-  end Pkg;
-
-Would Vec's "=" operator begin life as an abstract subprogram and then
-be transformed when the "=" operator for Drec is encountered?
-Let's just avoid the problem.
-
---------
-
-The same keep-it-simple logic applies to the idea of relaxing
-the instantiation restrictions in the case where the formal
-type has an abstract "=" operator.
 
-It does seem a bit odd to disallow
+Consider the following example:
+   package Pkg is
+     type Rec is null record;
+     function "=" (L, R) return Boolean is abstract;
 
-    type T is ... ; -- untagged, nonlimited, has abstract "=" operator
+     type Drec is new Rec; -- inherits abstract "="
 
-    generic
-        type D is new T;
-    package G is ... ; end G;
+     type Vec is array (Boolean) of Drec;
 
-    package I is new G (T);
+     function "=" (L, R : Drec) return Boolean;
+   end Pkg;
 
-So, we could include the exemption that is already discussed
-in the AI for a formal derived type which has an abstract "="
-operator. It's only the camel's nose, right?
-What about a formal array type which has an abstract "="
-operator (because its element type does)? Ok, just the nose
-and the muzzle.
+Vec's predefined "=" operator is defined in terms of that of Drec,
+which is defined in terms of the explicitly defined "=" operator.
 
-We should do enough to make this corner case (i.e., the use
-of untagged abstract-equality-op types) well-defined; there is no
-justification for adding complexity beyond that.
-
--------
-
-What about this one?
-
-    package P is
-      type T is limited private;
-      package Inner is
-        type Rec is record X : T; end record;
-      end Inner;
-    private
-      function "=" (L, R : T) return Boolean is abstract;
-      type T is null record;
-    end P;
-
-    package body P is
-      package body Inner is
-        X, Y : Rec;
-        Flag : Boolean := X = Y;
-      end Inner;
-    end P;
-
-We want to reject this example, but it's not clear what
-rule needs to be invented to handle this case.
-
-Perhaps a dynamic semantics rule to the effect that "if this
-rule would result in calling an abstract function, then
-do it the old way instead". If we are going to add such a
-rule, then perhaps we could get rid of the conservative
-static checks on instantiations.
-
-It seems that this approach is worth considering, particularly
-because we do have to do something with this example.
-
-Note that if the word "nonlimited" were deleted from
-
-  If the untagged record type has a nonlimited partial view, then the
-  declaration shall occur in the visible part of the enclosing package.
-
-, then the example could be modified by moving the function
-declaration from the beginning of the private part to the end
-of the visible part (swapping the order of two lines). Thus, that
-wouldn't solve the problem.
-
-----
-
-The need for the "immutably limited" business with formal
-derived types is illustrated by the following example:
+--------
 
-  package Pkg is
-    type T1 is limited private;
+Consider the following example:
+     package P is
+       type T is limited private;
+       package Inner is
+         type Rec is record X : T; end record;
+       end Inner;
+     private
+       function "=" (L, R : T) return Boolean is abstract;
+       type T is null record;
+     end P;
+
+     package body P is
+       package body Inner is
+         X, Y : Rec;
+         Flag : Boolean := X = Y;
+       end Inner;
+     end P;
 
-    generic
-      type D is new T1; -- not immutably limited
-    package G is
-    end G;
-  private
-    type T1 is null record;
-  end Pkg;
-
-  package body Pkg is
-    package body G is
-      X, Y : D;
-      Eq : Boolean := X = Y;
-    end G;
-  end Pkg;
-
-  with Pkg;
-  pragma Elaborate (Pkg);
-  package Client is
-    type T2 is new Pkg.T1;
-    function "=" (L, R : T2) return Boolean is abstract;
-    packge I is new Pkg.G (T2);
-  end Client;
+The elaboration of the declaration of Flag raises Program_Error.
 
 ----
 
@@ -348,14 +242,6 @@
 existing wording in 7.3.1(4/1) uses "The corresponding rule".
 Should the two agree? If so, then should 7.3.1 be changed?
 
------
-
-Is the treatment of "/=" correct in this AI?
-It would be good to review the wording with
-this in mind. The RM seems a little murky with
-respect to the status of "/=" in the case of
-an abstract "=" operator; perhaps I'm just confused.
-
 --------
 
 This would add the 25th occurrence in the
@@ -397,10 +283,6 @@
 be affected by this decision would be the predefined equality operator for
 some type which includes this array type as a component type.
 
-As the !wording section illustrates, the inconsistent treatment of
-records and arrays also cannot be justified on the grounds that it
-somehow simplifies the definition.
-
 !example
 
 ** TBD **
@@ -2182,7 +2064,7 @@
 ****************************************************************
 
 From: Randy Brukardt
-Sent: Friday, March 20, 2009  xx:xx PM
+Sent: Friday, March 20, 2009  9:15 PM
 
 >formatting error (wrong font, bad indentation) for
 >#2 in the "These cases are dealt with as follows" list, starting with 
@@ -2249,3 +2131,56 @@
 Maybe that's OK.
 
 ****************************************************************
+
+From: Steve Baird
+Sent: Monday, April 6, 2009  11:18 AM
+
+ > Steve: Make a new draft of AI-123.
+
+I did this and the writeup reflects the discussions of the group.
+However, it seems to me that the measures we are taking to statically prevent the
+invocation of an abstract equality operator are not worth the cost.
+
+How about a change in dynamic semantics so that this case may be allowed to occur
+(at least in some cases) and has well-defined dynamic semantics? If we want to, we
+could still statically reject the cases where we know precisely what is going on,
+as opposed to imposing assume-the-worst rules.
+
+Alternatives include
+   - for purposes of deciding whether an untagged unlimited
+     record type has a user-defined equality op (in this AI),
+     ignore abstract equality ops (i.e. revert to existing
+     Ada05 semantics in this case).
+
+   - raise Program_Error at the point where an abstract
+     equality operation would otherwise be invoked.
+
+I would favor the latter because presumably the user had a good reason for declaring
+the equality operator to be abstract.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, April 6, 2009  12:58 PM
+
+I would be in favor of the second, since it seems like a better alternative than
+adopting a mess of incompatible and weird assume-the-worst static rules. Indeed,
+I've tried to make the suggestion on considering dynamic rules several times in the
+past without much interest. Perhaps you need to write up an alternative set of rules
+so we can see whether it helps any to do that. (I think squirreling renames still
+would be a problem, for instance.)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Sunday, April 12, 2009  3:41 PM
+
+> Is the cure worse than the disease?
+> Should this whole AI should be abandoned?
+
+I (reluctantly) think so.  I say "reluctantly", since I was originally strongly
+in favor of this, but now I see it's getting out of hand.  It's just not worth it.
+At this point, I think the cure is indeed worse than the disease.
+
+****************************************************************
+

Questions? Ask the ACAA Technical Agent