CVS difference for ais/ai-50217.txt

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

--- ais/ai-50217.txt	2003/08/08 01:44:11	1.6
+++ ais/ai-50217.txt	2003/09/19 01:42:29	1.7
@@ -1,11 +1,11 @@
-!standard 10.01.02   (03)                           03-04-03  AI95-00217-06/02
+!standard 10.01.02   (03)                           03-09-09  AI95-00217-06/03
 !standard 10.01.02   (04)
 !standard 10.01.02   (08)
 !standard J.10       (00)
 !class amendment 03-02-04
 !status work item 03-02-04
 !status received 03-02-04
-!priority Medium
+!priority High
 !difficulty Hard
 !subject Limited With Clauses
 
@@ -26,21 +26,11 @@
 parameters), and to do this in a way that doesn't place any undue restrictions
 on the programmer.
 
-For mutually recursive types, it is valuable if subprogram parameters may be of
-the type itself, rather than only an access to the type. However, for most
-types, it may be necessary to see the full definition to know how parameters of
-the type are passed. However, because tagged types are always passed by
-reference, there is no implementation difficulty in allowing them to be used as
-parameters even when the full definition of the type is not available.  Hence,
-it makes sense to relax the rule for using incomplete types that are known to
-be tagged, to allow them as formal and actual parameters, since from a code
-generation point of view they are essentially equivalent to access parameters.
-
 !proposal
 
 A new kind of with_clause is added, of the form "limited with <library
 package names>;".  This is called a "limited_with_clause".  The old
-fashioned kind is called an "unlimited_with_clause".
+fashioned kind is called a "nonlimited_with_clause".
 
 There are two key features of a limited_with_clause such as "limited
 with X;":
@@ -48,11 +38,9 @@
     - It introduces no semantic dependence on X (and hence no
       elaboration dependence on X).  The implementation may choose to
       elaborate X either before or after the current unit.
-      [In the wording below, I ended up saying it introduces a semantic
-      dependence on the limited view of X.]
 
     - Instead of providing visibility to the named packages and their
-      content, it provides visiblility only to the package names, any
+      content, it provides visibility only to the package names, any
       packages nested within them, and a view of each type therein.
       The type view is incomplete, implying all the usual restrictions
       on incomplete types.  If the type is tagged, the view is tagged
@@ -62,62 +50,102 @@
 broken by at least one limited_with_clause.
 
 !wording
+
+Replace 3.10.1(10) by:
+
+A dereference (whether implicit or explicit -- see 4.1) is only allowed to be
+of an incomplete type T if it does not occur in the declarative region of [the
+incomplete type] T and:
+
+o  it occurs in the scope of a nonlimited_with_clause that mentions the library
+   package in which that completion is declared; or
+
+o  its expected type is the completion of T.
 
-Add after 8.3(20):
 
-The full view of a library package is hidden from all visibility within the
-scope of a limited_with_clause that mentions it. The limited view of a library
-package is hidden from all visibility within the declarative region of the
-package, and within the scope of a nonlimited_with_clause that mentions this
-package or a renaming thereof.
+Replace 4.1(9) by:
 
+If the type of the name in a dereference is some access-to-object type T, then
+the dereference denotes a view of an object.  The nominal subtype of that view
+is the designated subtype T, unless T is an incomplete type, in which case the
+nominal subtype is the completion of T.
 
+
+Change the beginning of 8.3(20):
+
+The declaration of a library unit (including a
+library_unit_renaming_declaration) is hidden from all visibility except at
+places that are within its declarative region or within the scope of a
+nonlimited_with_clause that mentions it.  The limited view of a library package
+is hidden from all visibility except at places that are within the scope of a
+limited_with_clause that mentions it but not within the scope of a
+nonlimited_with_clause that mentions it.
+
 Replace 8.4(5) by:
 
 A package_name of a use_package_clause shall denote a non-limited view of a
 package.
 
 
+Add after of 8.4(10):
+
+o  A potentially use-visible declaration is not visible if the place considered
+   is within the scope of a limited_with_clause which mentions the package
+   where the declaration occurs, and is more nested than the use_clause.
+
+
 Replace 8.5.3(3) by:
 
 The renamed entity shall be a non-limited view of a package.
 
 
+Insert somewhere in 10.1.1(26):
+
+A limited library package view declaration depends semantically upon the parent
+limited package view declaration.  A library package declaration depends
+semantically upon its limited view.
+
+
 Replace 10.1.2(4) by:
 
-  with_clause ::= limited_with_clause | unlimited_with_clause
-  limited_with_clause ::= limited with library_unit_name {, library_unit_name};
-  unlimited_with_clause ::=       with library_unit_name {, library_unit_name};
+  with_clause ::= limited_with_clause | nonlimited_with_clause
+  limited_with_clause  ::= limited with library_unit_name {, library_unit_name};
+  nonlimited_with_clause ::=       with library_unit_name {, library_unit_name};
 
 Add after 10.1.2(5):
 
 A with_clause is *more nested than* a context_item if they are both part of the
 same context_clause, or if the scope of the with_clause is entirely included in
-the scope of the context_item.
+the scope of the context_item. Similarly, a with_clause is *more nested than* a
+use_clause occurring immediately within a declarative region, if the scope of
+the with_clause is entirely included in the scope of the use_clause.
 
 Replace 10.1.2(6) by:
 
-A library_item is *explicitly mentioned* in a with_clause if it is denoted by a
+A library_item is *named* in a with_clause if it is denoted by a
 library_unit_name in the with_clause. A library_item is mentioned in a
-nonlimited_with_clause if it is explicitly mentioned or if it is denoted by a
-prefix in the with_clause. A library_item is mentioned in a limited_with_clause
-if it is explicitly mentioned or if it is denoted by a prefix in the
-with_clause, and that with_clause is not more nested than a
+nonlimited_with_clause if it is named in the with_clause or if it is denoted by
+a prefix in the with_clause. A library_item is mentioned in a
+limited_with_clause if it is named in the with_clause or if it is denoted by a
+prefix in the with_clause, and that with_clause is not more nested than a
 nonlimited_with_clause that mentions the same library_item. A name mentioned in
 a limited_with_clause denotes the limited view of the corresponding library
 package.
 
+
 Add after 10.1.2(8):
 
 A library_item mentioned in a limited_with_clause shall be a
 package_declaration[, not a subprogram_declaration, generic_declaration,
-or generic_instantiation].
+generic_instantiation, or package_renaming_declaration].
 
-A limited_with_clause which explicitly mentions a library_item shall not be
-more nested than a nonlimited_with_clause or use_clause which mentions the same
-library_item or a renaming thereof.
+A limited_with_clause which names a library_item shall not be more nested than
+a nonlimited_with_clause which mentions the same library_item.
 
-Add after 10.1.4(3):
+A limited_with_clause shall not appear on a library_unit_body or subunit.
+
+
+Add after 10.1.4(2):
 
 In addition, for each library_package_declaration in the environment, there is
 a conceptual declaration of a *limited view* of that library package. The
@@ -131,28 +159,29 @@
    incomplete.
 
 The limited view of a package has the same identifier as the
-package_declaration.
+package_declaration. It is private or public according to the declaration of
+the corresponding library_package_declaration.
 
 There is no syntax for declaring limited package views, because they are always
-implicit.  Nonetheless, the declaration of a limited package view is considered
-to be a library_item.
+implicit.  A limited package view is _not_ the declaration of a library unit
+(the library_package_declaration is).  Nonetheless, the declaration of a
+limited package view is considered to be a library_item.
 
 A library_package_declaration is considered to be the completion of its limited
 view declaration.
 
+Add after 10.1.4(3):
 
-Insert somewhere in 10.1.1(26):
+The mechanisms for adding a unit mentioned in a limited_with_clause within an
+environment are implementation defined.
 
-A limited library package view declaration depends semantically upon the parent
-limited package view declaration.  A library package declaration depends
-semantically upon its limited view.  [Author's Note: Not sure what is the
-purpose of the first rule.]
+Add after 10.2(6):
 
+o  If the limited view of a unit is needed, then the full view of the unit is
+   needed.
 
 !discussion
 
-Discussion of existing wording:
-
 It is natural to think of a with_clause as causing a library unit to
 become visible.  However, that's not what the RM says.  Instead, the RM
 says that *lack* of a with_clause causes a library unit *not* to be
@@ -177,20 +206,12 @@
 
 Similar oddities occur in the definition of "immediate scope" and
 "scope".
-
-I'm not sure what's the best way to introduce limited_with_clauses into
-this model.  One idea is to say that "limited with X" means you can see
-X even if X occurs later in the environment declarative_part.  This
-would introduce (conceptual) forward references, something never seen in
-Ada before.  Another idea is to say that there is an implicit
-declaration of a "limited view of package X" (occurring before any
-"limited with X"'s).  The normal declaration of X then appears later in
-its usual place.  Either way, "limited with X" introduces a very limited
-view of X that only includes nested packages and incomplete types.  I
-think I'll try the latter idea, even though I hate to introduce yet more
-magical implicit junk.
 
-Discussion of new wording:
+The best way to introduce limited_with_clauses into this model is to say that
+there is an implicit declaration of a "limited view of package X" (occurring
+before any "limited with X"'s). The normal declaration of X then appears later
+in its usual place. "Limited with X" introduces a very limited view of X that
+only includes nested packages and incomplete types.
 
 We need to define the nesting of with_clauses relative to each other and to
 use_clauses to phrase a number of rules that describe the interaction between
@@ -200,19 +221,19 @@
 
 For nonlimited_with_clauses, the new 10.1.2(26) doesn't change the current RM.
 For limited_with_clause, it says that if for instance the specification of Q
-has a "with P" and the body of Q has a "limited with P.R.S" then P is not
-mentioned in the limited_with_clause. So the limited_with_clause has no effect
-for P; in particular it doesn't revert to the limited view of P. On the other
-hand, it makes the limited views of P.R and P.R.S visible. This is mostly a
-methodological restriction, as we have (pathological) cases where the limited
-view hides the full view. However, we want to make such cases infrequent to
-avoid confusing users.
+has a "with P" and the specification of Q.C has a "limited with P.R.S" then P
+is not mentioned in the limited_with_clause. So the limited_with_clause has no
+effect for P; in particular it doesn't revert to the limited view of P. On the
+other hand, it makes the limited views of P.R and P.R.S visible. This is mostly
+a methodological restriction, as we have (pathological) cases where the limited
+view "reemerges". However, we want to make such cases infrequent to avoid
+confusing users.
 
 The changes to 10.1.2(8) ensure that, if for instance the specification of Q
-has a "with P.R", it shall not have a "limited with P" or a "limited P.R". The
-same applies to the body of Q, its subunits, etc. On the other hand, a "limited
-with P.R.S" is fine. Again this is to avoid reverting to the limited view as
-much as possible.
+has a "with P.R", it shall not have a "limited with P" or a "limited with P.R".
+The same applies to the children of Q. On the other hand, a "limited with
+P.R.S" is fine. Again this is to avoid reemergence of the limited view as much
+as possible.
 
 The fact that a "limited with P" hides the full view of P from all visibility
 prevents ripple effects. If you are is the scope of a "limited with P", the
@@ -235,31 +256,82 @@
 would need to be resolved, and that would required full-fledged visibility
 analysis.
 
-A limited view of a package cannot be mentioned in a use clause to avoid a
-funky kind of Beaujolais effect where changing a with_clause causes the meaning
-of an identifier to switch from one interpretation to another:
+To simplify implementation and avoid funky Beaujolais effects, use clauses are
+not allowed to mention a limited view of a package.  Consider the example
+below; if the use clauses were legal, changing the "with A" to "with B" would
+silently change the meaning of X in P.C:
 
     package A is
-        X : Integer := 7;
+        X : Integer := 42;
     end A;
 
     package B is
-        X : Integer := 203;
+        X : Integer := 666;
     end B;
 
-    with A; -- change this to "with B;" and see what happens
-    package P is end;
+   limited with A;
+   limited with B;
+   use A, B; -- Illegal, really.
+   package P is
+   end P;
+
+   with A; -- Change this to "with B" and it changes the meaning of X.
+   package P.C is
+      Y : Integer := X;
+   end P.C;
+
+Furthermore, use clauses are inherited from the parent unit.  This may be used
+to construct a situation where a limited_with_clause occurs in the scope of a
+use_clause for the same unit.  For example:
+
+   with A;
+   package P is
+      package R renames A;
+   end P;
+
+   with P;
+   package Q is
+      use P.R; -- Makes A use-visible.
+   end Q;
+
+   limited with A;
+   package Q.C is
+      -- A _not_ use-visible here.
+   end Q.C;
+
+In this situation we say that the declarations in A are _not_ use-visible in
+the scope of the limited_with_clause. They are still potentially use-visible
+to prevent a Beaujolais effect illustrated by the following example (assume the
+same declaration for A and B as above):
+
+   with A, B;
+   package P is
+      package RA renames A;
+      package RB renames B;
+   end P;
+
+   with P;
+   package Q is
+      use P.RA, P.RB; -- Makes A and B use-visible.
+   end Q;
+
+   limited with A; -- Make this one a nonlimited "with"...
+   with B;         -- ... and this one a "limited with"
+   package Q.C is
+      Y : Integer := X; -- Illegal, really.
+   end Q.C;
+
+The rules are such that both Xs are made potentially use-visible, so the name X
+is illegal. If P.RA.X was not made potentially use-visible, the name X would
+resolve to P.RB.X, and its meaning would change when switching the with_clause
+as explained in the example.
+
+If you nest (in that order) (1) a use_clause, (2) a limited_with_clause and (3)
+a nonlimited_with_clause, then the limited_with_clause effectively cancels the
+use_clause, but the nonlimited_with_clause doesn't reestablish it.  Again,
+that's to prevent Beaujolais effects.
 
-    limited with A, B;
-    use A, B; -- Shouldn't be allowed
-    package P.C is
-        Y : Integer := X; -- which X is this?
-    end P.C;
-
-[This is an example that Tucker sent a while back. But is there a problem now
-that the limited_with_clause above is illegal?]
-
-Also, a limited view of a package cannot be mentioned in a package renaming
+A limited view of a package cannot be mentioned in a package renaming
 declaration. This restriction is probably not as critical as the others. The
 problem comes when someone from outside the unit containing the limited with
 references this package renaming. What does it see? If it has a "regular" with
@@ -272,27 +344,63 @@
 has no mechanism to deal with that.  Similarly, we do not allow a
 limited_with_clause to mention a generic, because that would allow
 instantiating a generic before its spec is elaborated.
-
-We do not allow a limited_with_clause to mention a generic instantiation,
-because that would require all kinds of semantic analysis stuff, such as
-visibility.
 
+We do not allow a limited_with_clause to mention a generic instantiation or a
+renaming, because that would require all kinds of semantic analysis stuff, such
+as visibility.
+
+The applicable nonlimited_ and limited_with_clauses determine (1) which
+entities are visible, (2) which dereferencing are legal and (3) what is the
+type of dereferences. In particular:
+
+1 - Consider an expanded name P.X. X is visible if either the name is within
+    the scope of a "with P" or if it is within the scope of a "limited with P"
+    and it is part of the limited view (if other words, it is a nested type or
+    package).
+
+2 - Consider a dereference X.all, where X is of an access-to-incomplete type
+    with designated type T. This dereference is illegal unless it occurs in
+    the scope of a "with P" (where P is the package that declares T), within
+    the immediate scope of the completion of T, or in a context where the
+    expected type is the completion of T.
+
+3 - Dereferencing an access-to-incomplete type (when it is legal) yields a name
+    whose nominal subtype is the completion of T. This makes it possible to
+    write an expression like X.all.Comp (assuming that we have the visibility
+    necessary to know that Comp exists).
 
-Open Issues:
-
 There are various places in Chapter 8 that refer to "the declaration of a
-library unit", presuming that there's only one.  We need to change the wording,
-since library packages now have two declarations: the limited view, plus the
-normal package_decl.  With minor wording changes, most of it should work OK,
-because:
-
-    A library_package_decl is the completion of its limited view,
-    and therefore hides it from all visibility.
-
-    The incomplete types in the limited view are completed by the
-    regular types.  This introduces the possibility of completing an
-    incomplete type with a private type, but I think all the proposals
-    are going to have a similar problem (if it's a problem).
+library unit", presuming that there's only one. We need to change the wording.
+One option is to say that library packages now have two declarations: the
+limited view, plus the normal package_declaration. Another option is to say
+that "the declaration of a library unit" is the normal package_declaration, the
+limited view being "something else". The latter option seems simpler, as it
+only requires to tweak 8.3(20) and doesn't interact with other parts of the
+language (e.g. freezing rules, library unit pragmas) like the former option
+would do.
+
+The part about the "declarative region of the incomplete type" in the wording
+of 3.10.1(10) is intended to forbid a case like:
+
+   package P is
+   private
+      type T;
+      type Ref is access T;
+      Ptr : Ref;
+   end P;
+
+   with P;
+   package body P is
+      Too_Early : Integer := Ptr.all'Size; -- Illegal.
+      type T is ...;
+   end P;
+
+Here the dereference is illegal because it occurs in the declarative region of
+the incomplete type T, and the nonlimited_with_clause doesn't make it legal.
+Note that a dereference that would occur after the completion of T would not be
+of an incomplete type, so 3.10.1(10) would not apply; consequently, such a
+dereference would be legal even though it would be in the declarative region of
+the incomplete type T.
 
 !example
 
@@ -3441,7 +3549,7 @@
 -----------------
 Thoughts on the implementation of "limited with" in AdaMagic
 
-          $Revision: 1.6 $ $Date: 2003/08/08 01:44:11 $
+          $Revision: 1.7 $ $Date: 2003/09/19 01:42:29 $
 
 The "limited with" clause makes a "limited view"
 of a package visible in the compilation unit
@@ -5250,7 +5358,7 @@
 -----------------
 Thoughts on the implementation of "limited with" in AdaMagic
 
-          $Revision: 1.6 $ $Date: 2003/08/08 01:44:11 $
+          $Revision: 1.7 $ $Date: 2003/09/19 01:42:29 $
 
 The "limited with" clause makes a "limited view"
 of a package visible in the compilation unit

Questions? Ask the ACAA Technical Agent