Version 1.1 of acs/ac-00180.txt

Unformatted version of acs/ac-00180.txt version 1.1
Other versions for file acs/ac-00180.txt

!standard 5.2(5/2)          09-10-29 AC95-00180/01
!class confirmation 09-10-29
!status received no action 09-10-29
!status received 09-10-28
!subject What does nonlimited type mean?
!summary
!appendix

!topic What does "nonlimited type" mean in 5.2?
!reference 5.2(5/2)
!from Adam Beneschan 09-10-28
!discussion


I'm having trouble understanding a really simple statement in the RM.
For an assignment statement:

5.2(5/2) The target denoted by the variable_name shall be a variable
   of a nonlimited type.

My problem with this is that types can have both limited and nonlimited views.
So I presume that the "nonlimited type" refers to a nonlimited *view* of a type.
(See also AI05-80.)  In fact, it would have to be that way, because if we have
this declaration:

   package Pack1 is
      type T1 is limited private;
   private
      type T1 is record   -- not limited!
        ...
      end record;
   end Pack1;

then the legality of something like

   declare
     X, Y : Pack1.T1;
   begin
     X := Y;
   end;

depends on which declaration of T1 (partial or full) is visible.  The block
would be legal in the body of Pack1 or one of its children, and illegal anywhere
else.

But this leads to the question, how do we determine which view of the type of
the target variable in an assignment statement is in effect? When a type is
referred to by name, the answer is pretty clear---if we're in the scope of the
full view of the type, the name denotes the full view (and denotes a limited
type depending on whether that full view is limited); otherwise the name denotes
the partial view (etc.).

But here, the type is not named, and *no* declaration of the type might be
visible:

   package Pack2 is
       type T is (A, B, C);
   end Pack2;

   with Pack2;
   package Pack3 is
       V : Pack2.T;
       function Foo return Pack2.T;
   end pak2;

   with Pack3;
   procedure Proc4 is
   begin
       Pack3.V := Pack3.Foo;
   end Proc4;

The assignment statement is not in the scope of Pack2.T's declaration.
Therefore, when the compiler tries to determine whether the variable has a
"nonlimited type", as 5.2(5) requires, how is this determined? I can't find
where in the RM it says.

(Note that AARM 7.5(16.b) says "'limited' is a property that depends on where
you are in the scope of the type", which doesn't help at all if you are not
anywhere in the scope of the type.)

Unless there's something I haven't found, I think the RM needs additional
language to clarify exactly what "nonlimited type" means in 5.2(5).  Maybe
something like, "The variable's type is considered to be nonlimited if a
nonlimited view of the type was declared by one of the declarative_items of a
declarative_part or by one of the basic_declarative_items in the visible part of
a package, or if the assignment statement is in the scope of a nonlimited view
of the type, or if the type is an anonymous access type".  (I'm assuming that
all types other than anonymous access types are declared by basic_declarations.)
Is that close to the intent?

The question came up while I was looking at a test submitted for the ACATS (as
far as I know, the test was not included).  The relevant code looked something
like this:

    package Pack1 is
    end Pack1;

    package Pack1.Pack2 is
    end Pack1.Pack2;

    package Pack1.Pack2.Pack3 is
        type T is tagged null record;
    end Pack1.Pack2.Pack3;

    with Pack1.Pack2.Pack3;
    package Pack1.Pack2.Pack4 is
        A : Pack1.Pack2.Pack3.T;
    end Pack1.Pack2.Pack4;

    limited with Pack1.Pack2.Pack3;
    procedure Pack1.Pack2.Proc5 (Y : access Pack1.Pack2.Pack3.T);

    with Pack1.Pack2.Pack4;
    procedure Pack1.Pack2.Proc5 (Y : access Pack1.Pack2.Pack3.T) is
        W : Pack1.Pack2.Pack3.T renames Y.all; -- ERROR:
    begin
        Pack1.Pack2.Pack4.A := Y.all;          -- OK
    end Pack1.Pack2.Proc5;

I was going nuts trying to figure out why the assignment statement was legal
even though only the limited view of A's type was available (because
Pack1.Pack2.Pack3 was LIMITED WITH'ed---3.10.1(2.1)).  After looking through the
RM for a while I decided that something seemed to be missing.

****************************************************************

From: Bob Duff
Date: Wednesday, October 28, 2009  5:39 PM

> My problem with this is that types can have both limited and
> nonlimited views.  So I presume that the "nonlimited type" refers to a
> nonlimited *view* of a type.  (See also AI05-80.)

Right, I think AI05-80 is the best answer to this sort of question.
We can't very well go sprinkling "view of" all over the RM -- we'd introduce
more bugs than we'd fix.

...
> The assignment statement is not in the scope of Pack2.T's declaration.

Actually, it is.  See 8.2.  Scope of T extends to the end of the declarative
region of Standard, excluding non-semantic-dependents of Pack2. Proc4 is a
semantic dependent of Pack2 -- "semantic dependence" is a transitive
relationship.

So although T is not visible at the assignment statement, it is in scope.  If T
were private, the private view, but not the full view, would be in scope.

****************************************************************

From: Adam Beneschan
Date: Wednesday, October 28, 2009  6:00 PM

Aack, I guess you're right.  I missed the recursion in 8.2(10), and I sometimes
have trouble keeping the differences between "scope", "immediate scope", and the
different kinds of "visibility" straight.

So I guess I did miss something, this time.  Sorry.

****************************************************************

Questions? Ask the ACAA Technical Agent