CVS difference for ais/ai-00235.txt

Differences between 1.5 and version 1.6
Log of other versions for file ais/ai-00235.txt

--- ais/ai-00235.txt	2000/06/21 23:39:10	1.5
+++ ais/ai-00235.txt	2000/12/06 21:46:44	1.6
@@ -1,5 +1,6 @@
-!standard 03.10.02  (02)                               00-06-16  AI95-00235/03
+!standard 03.10.02  (02)                               00-11-28  AI95-00235/04
 !class binding interpretation 00-05-31
+!status ARG Approved 8-0-3  00-11-19
 !status work item 00-05-09
 !status received 00-05-09
 !priority High
@@ -43,15 +44,16 @@
 
 Replace 3.10.2(2) with:
     For an attribute_reference with attribute_designator Access (or
-    Unchecked_Access -- see 13.10), the expected type shall be
-    a single access type whose designated type covers the type of
-    the prefix, or, if the type of the prefix is D'Class, whose
-    designated type is D, or whose designated profile is type conformant with
-    that of of the prefix. [The prefix of such an attribute_reference
-    is never interpreted as an implicit_dereference or parameterless
-    function_call (see 4.1.4).] The designated type or profile of the
-    expected type of the attribute_reference is the expected type or
-    profile for the prefix.
+    Unchecked_Access -- see 13.10), the expected type shall be a single access
+    type A such that:
+        A is an access to object type with designated type D and the type of
+         the prefix is D'Class or is covered by D, or
+        A is an access to subprogram type whose designated profile is type
+         conformant with that of the prefix.
+    [The prefix of such an attribute_reference is never interpreted as an
+    implicit_dereference or parameterless function_call (see 4.1.4).] The
+    designated type or profile of the expected type of the attribute_reference
+    is the expected type or profile for the prefix.
 
 !discussion
 
@@ -72,9 +74,9 @@
 
      if Do_It (Value'Access) then ... -- Illegal by original RM rule.
 
-(Code like this is common in interfacing packages, where an anonymous access
-type used to implement *p parameters in functions [because In Out parameters
-are not allowed there]).
+Code like this is common in interfacing packages, where an anonymous access
+type used to implement *p parameters in functions (because In Out parameters
+are not allowed there).
 
 To work around the problem caused by the original RM rule, a named access type
 has to be introduced, so that it can be used in a qualified expression:
@@ -111,14 +113,15 @@
 @dby
 For an @fa<attribute_reference> with @fa<attribute_designator> Access (or
 Unchecked_Access -- see 13.10), the expected type shall be
-a single access type whose designated type covers the type of
-the @fa<prefix>, or, if the type of the @fa<prefix> is D'Class, whose
-designated type is D, or whose designated profile is type conformant
-with that of the @fa<prefix>. The @fa<prefix> of such an
-@fa<attribute_reference> is never interpreted as an @fa<implicit_dereference>
-or parameterless @fa<function_call> (see 4.1.4). The designated type or profile
-of the expected type of the @fa<attribute_reference> is the expected type or
-profile for the @fa<prefix>.
+a single access type A such that:
+@xbullet<A is an access to object type with designated type D and the type of
+the @fa<prefix> is D'Class or is covered by D, or>
+@xbullet<A is an access to subprogram type whose designated profile is type
+conformant with that of the prefix.>
+The @fa<prefix> of such an @fa<attribute_reference> is never interpreted as an
+@fa<implicit_dereference> or parameterless @fa<function_call> (see 4.1.4).
+The designated type or profile of the expected type of the
+@fa<attribute_reference> is the expected type or profile for the @fa<prefix>.
 
 !ACATS test
 
@@ -1762,6 +1765,342 @@
 name for the type represented by D in D'Class for a classwide type? The closest
 I can come is "specific" type, but I don't think that is right. Perhaps there
 isn't one, but perhaps there should be?
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, November 28, 2000 7:37 AM
+
+During the last meeting, we came to an agreement on the name resolution
+rules that should apply to the prefix of 'Access (and 'Unchecked_Access).
+
+But it seems to me that we still need to fix the first sentence of RM95
+3.10.2(27) which reads (in the corrigendum):
+
+"If A is a named access type and D is a tagged type, then the type of the
+view shall be covered by D; if A is anonymous and D is tagged, then the type
+of the view shall be either D'Class or a type covered by D; ..."
+
+The distinction between named and anonymous access types was introduced as
+part of AI95-00127 to permit dispatching.  As written, this rule makes the
+following code fragment illegal:
+
+    type T is tagged null record;
+    type A_T is access all T;
+
+    Y : aliased T'Class := T'(null record);
+
+    Z : A_T := Y'Access; -- ERROR
+
+because A_T is a named access type and the type of Y (T'Class) is not
+covered by T.
+
+I believe that the distinction between named and anonymous access types
+should be now removed from 3.10.2(27):
+
+"If D is a tagged type, then the type of the view shall be either D'Class or
+a type covered by D; ..."
+
+*************************************************************
+
+From: Randy Brukard
+Sent: Tuesday, November 28, 2000 4:45 PM
+
+Pascal wrote:
+
+> During the last meeting, we came to an agreement on the name resolution
+> rules that should apply to the prefix of 'Access (and 'Unchecked_Access).
+>
+> But it seems to me that we still need to fix the first sentence of RM95
+> 3.10.2(27) which reads (in the corrigendum):
+>
+> "If A is a named access type and D is a tagged type, then the type of the
+> view shall be covered by D; if A is anonymous and D is tagged, then the type
+> of the view shall be either D'Class or a type covered by D; ..."
+>
+> The distinction between named and anonymous access types was introduced as
+> part of AI95-00127 to permit dispatching.  As written, this rule makes the
+> following code fragment illegal:
+>
+>     type T is tagged null record;
+>     type A_T is access all T;
+>
+>     Y : aliased T'Class := T'(null record);
+>
+>     Z : A_T := Y'Access; -- ERROR
+>
+> because A_T is a named access type and the type of Y (T'Class) is not
+> covered by T.
+>
+> I believe that the distinction between named and anonymous access types
+> should be now removed from 3.10.2(27):
+>
+> "If D is a tagged type, then the type of the view shall be either D'Class or
+> a type covered by D; ..."
+
+This change seems to be only loosely related to AI-235. The point of the AI-235
+is to allow the type of the prefix to be used in the resolution of 'Access. This
+comment seems to be suggesting to allow more kinds of prefix to be allowed.
+
+As Pascal noted, the current legality rule was created (in AI-127) to permit
+dispatching operands to be 'Access or an allocator. It was not to allow more
+(implicit) conversions in general. Thus, the rule was restricted to anonymous
+access types, which must be a parameter, and which are likely to be controlling.
+There doesn't seem to have been any reason that the rule of AI-127 couldn't have
+applied to all access types; thus I have to assume that it was a conscious
+decision (given that the wording is some much more complex this way).
+
+Pascal's example does not contain any dispatching, so it is a different issue
+than that implied by AI-127; and it clear that it is a different issue than
+AI-235 as well. (If his proposed change is made, the example is legal whether or
+not AI-235 is adopted.)
+
+Note that AI-235 allows "If D is a tagged type, then the type of the view shall
+be either D'Class or a type covered by D" in the resolution rule, as insisting
+that the access type is anonymous would complicate the resolution rule with no
+gain. It is not intending to allow prefixes not allowed currently, but simply to
+allow prefixes (or the type of a parameter) to be overloaded.
+
+Note that if Pascal's proposed change was adopted, 'Access and allocators would
+be inconsistent as to the types allowed (4.8(3) has the same rule). If we make
+the change, it should be made there as well.
+
+That is, both of the following are illegal in the current standard, and I don't
+see any reason to change one without changing the other:
+
+>     Z : A_T := Y'Access; -- ERROR:
+>     ZZ: A_T := new T'Class(Y); -- ERROR:
+
+In any event, I don't see any reason to make this change in AI-235. I could see
+making it a separate AI, but I guess I'd like to see a compelling reason for
+the change. "Because we can" doesn't seem to be a good reason for language
+design; we *can* implicitly convert *everything* to everything else, but we
+know this is a bad idea.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, November 28, 2000 5:40 PM
+
+Randy Brukardt wrote:
+> ...
+> Pascal's example does not contain any dispatching, so it is a different
+> issue than that implied by AI-127; and it clear that it is a different issue
+> than AI-235 as well. (If his proposed change is made, the example is legal
+> whether or not AI-235 is adopted.)
+> ...
+> In any event, I don't see any reason to make this change in AI-235. I could
+> see making it a separate AI, but I guess I'd like to see a compelling reason
+> for the change. "Because we can" doesn't seem to be a good reason for
+> language design; we *can* implicitly convert *everything* to everything
+> else, but we know this is a bad idea.
+
+I agree with Randy that we don't want to make this change.
+In general, we only allow "implicit" conversion from T'Class
+to T as part of dispatching.  We definitely considered allowing
+it in more cases during Ada 9X, but decided against for what
+I am sure were good reasons at the time (though please don't
+ask me to repeat them right now ;-).
+
+See 3.9.2(9) for the rule that disallows the T'Class => T conversion
+except as part of dispatching.  Note that this is a case where overload
+resolution allows the conversion, but a specific legality rule
+disallows it.  That is, the overload resolution rule is more permissive
+than the legality rule.
+
+As I think about it more, I am beginning to remember some of the
+"good" reasons.  Reading the AARM (3.9.2(9a)) also helps remind me.
+Basically, converting from T'Class to T is a kind of "truncation."  If
+this is coupled with dispatching, there is no problem.  However, when not
+coupled with dispatching, it allows a potentially confusing
+truncation to occur.  I realize that with access types, no real
+truncation is happening.  However, conversion to specific ancestors
+(as opposed to classwide ancestors) is in some cases privacy-breaking,
+and we certainly don't want that to occur without an explicit
+conversion visible in the code.
+
+Now that I have mentioned these privacy-breaking conversions, I would
+like to put in a request that we define a configuration pragma to outlaw
+them, and perhaps make them obsolescent in Ada 200X.  A privacy-breaking
+conversion is any (non-dispatching) conversion from a class-wide type to
+a specific type, or a conversion from a specific type to a specific ancestor
+type when there is at least one private extension involved in the chain from
+the ancestor to the descendant.
+
+Such conversions are "privacy breaking" because the
+operations on the target type might not preserve all
+the invariants associated with the source object's (run-time) type.
+If all the extensions between two types are visible record extensions,
+then there can't be much of an invariant to be preserved anyway.
+However, as soon as there is at least one private extension involved,
+fields within that private extension might be required to be kept
+in "sync" whenever components of the target/ancestor type are updated,
+and this obviously couldn't be done by the operations of the ancestor
+type.
+
+For example, given:
+
+    type T is tagged ...
+    procedure Update(X : in out T);
+
+    type NT is new T with private;
+    procedure Update(X : in out NT);
+
+  . . .
+
+    Y : NT;
+    Z : T'Class := Y;
+
+  . . .
+
+    Update(T(Y));  -- This is privacy breaking
+    Update(T(Z));  -- So is this
+    Update(T'Class(Y));  -- This is OK, because it dispatches
+
+Of course, "Update(T(Y));" would be allowed within the scope
+of the full view of NT, because the extension is visible there,
+and this kind of conversion is important to support the typical
+"pass-the-buck" style of programming.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, November 29, 2000 4:01 AM
+
+> I agree with Randy that we don't want to make this change.
+> In general, we only allow "implicit" conversion from T'Class
+> to T as part of dispatching.
+> ...
+> Basically, converting from T'Class to T is a kind of "truncation."  If
+> this is coupled with dispatching, there is no problem.  However, when not
+> coupled with dispatching, it allows a potentially confusing
+> truncation to occur.  I realize that with access types, no real
+> truncation is happening.
+
+OK, I understand, that makes sense.  Objection withdrawn.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, November 29, 2000 5:30 AM
+
+> See 3.9.2(9) for the rule that disallows the T'Class => T conversion
+> except as part of dispatching.  Note that this is a case where overload
+> resolution allows the conversion, but a specific legality rule
+> disallows it.  That is, the overload resolution rule is more permissive
+> than the legality rule.
+
+Now that you have drawn my attention to 3.9.2(9), I believe that as written
+now it defeats the purpose of AI95-00235.  Consider:
+
+    type T is tagged null record;
+
+    function F (X : access T) return Boolean;
+
+    Y : aliased T'Class := T'(null record);
+
+    B : Boolean := F (Y'Access);
+
+The AI tells us that (1) the expected type for Y'Access is the anonymous
+"access T" and (2) the expected type for Y in Y'Access is T.
+
+At this point the first sentence of 3.9.2(9) kicks in: the expected type for
+Y is T, which is a specific tagged type, and Y is dynamically tagged, so
+it's illegal.
+
+Note that this happens because the prefix of 'Access now has an expected
+type, while previously it had to be resolved independently of the context;
+in other words, we have an implicit conversion of Y to T, and this implicit
+conversion is not a controlling operand.
+
+So I think that the first sentence of 3.9.2(9) needs to be revised along the
+lines of:
+
+"... unless it is a controlling operand in a call on a dispatching
+operation, or the prefix of an Access or Unchecked_Access attribute which is
+a controlling operand in a call on a dispatching operation."
+
+But this is not quite right because the part about attributes should also
+take into account attributes that appear in parenthesized expressions or
+qualified expressions.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, November 29, 2000 8:40 AM
+
+> So I think that the first sentence of 3.9.2(9) needs to be revised along the
+> lines of:
+>
+> "... unless it is a controlling operand in a call on a dispatching
+> operation, or the prefix of an Access or Unchecked_Access attribute which is
+> a controlling operand in a call on a dispatching operation."
+
+This may not be necessary, because the "controlling operand" in
+the example you give above is in fact "Y", not "Y'Access," so the
+first sentence of 3.9.2(9) already covers it.  See 3.9.2(2), where it says:
+
+   ... If the controlling formal parameter is an access parameter, the
+   controlling operand is the object designated by the actual parameter,
+   rather than the actual parameter itself.  ...
+
+>
+> But this is not quite right because the part about attributes should also
+> take into account attributes that appear in parenthesized expressions or
+> qualified expressions.
+
+Can you give some examples of these?  I think the definition of
+"controlling operand" solves these as well.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, November 29, 2000 8:54 AM
+
+> This may not be necessary, because the "controlling operand" in
+> the example you give above is in fact "Y", not "Y'Access," so the
+> first sentence of 3.9.2(9) already covers it.  See 3.9.2(2), where it says:
+>
+>    ... If the controlling formal parameter is an access parameter, the
+>    controlling operand is the object designated by the actual parameter,
+>    rather than the actual parameter itself.  ...
+
+I see.  Missed that subtlety.
+
+> > But this is not quite right because the part about attributes should also
+> > take into account attributes that appear in parenthesized expressions or
+> > qualified expressions.
+>
+> Can you give some examples of these?  I think the definition of
+> "controlling operand" solves these as well.
+
+I was thinking of something like:
+
+    B : Boolean := F ((((Y'Access))));
+
+but you're right, the above paragraph has the right effect in this case.
+
+*************************************************************
+
+From: Robert A Duff
+Sent: Wednesday, November 29, 2000 9:38 AM
+
+> In any event, I don't see any reason to make this change in AI-235. I could
+> see making it a separate AI, but I guess I'd like to see a compelling reason
+> for the change. "Because we can" doesn't seem to be a good reason for
+> language design; we *can* implicitly convert *everything* to everything
+> else, but we know this is a bad idea.
+
+The language design principle for conversions is that conversions that
+"make sense", and cannot lose information, and cannot fail at ruin time,
+should be implicit.  Others should be explicit (if allowed at all).  By
+"make sense", I mean not violating the type system -- converting apples
+to oranges or whatever should be explicit.
+
+Unfortunately, the above principle conflicts with the principle of
+upward compatibility.
+
+I like the typo "ruin time"; I think I'll leave it in.  ;-)
 
 *************************************************************
 

Questions? Ask the ACAA Technical Agent