Version 1.1 of acs/ac-00132.txt

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

!standard 10.1.1(19/2)          06-06-02 AC95-00132/01
!standard 12.3(11)
!class confirmation 06-06-02
!status received no action 06-06-02
!status received 06-05-11
!subject Legality checking for implicitly declared generics
!summary
!appendix

From: Stephen W. Baird
Date: Thursday, Map 11, 2006  4:28 PM

RM05 10.1.1(19/2) specifies the "sprouting" rules by which a child unit C
of a parent generic package P causes the existence of a corresponding
declaration nested immediately within each instance of P.

At what point, if any, are Legality Rules enforced for these declarations?

Consider the following example:

  generic
    type T is private;
  package Parent is
  end Parent;

  ----

  generic
  package Parent.Child is
    type Tg is tagged null record;
    procedure Proc (X : Tg; Y : Parent.T);
    procedure Proc (X : Tg; Y : Integer);
  end Parent.Child;

  ----

  with Parent;
  package Parent_Instance is new Parent (Integer);

  ----

  with Parent_Instance;
  with Parent.Child;
  package Client_1 is
  -- Parent_Instance.Child is visible, but unreferenced
  end Client_1;

  ----

  with Parent_Instance;
  with Parent.Child;
  package Client_2 is
    generic package Ren renames Parent_Instance.Child;
    -- Parent_Instance.Child is referenced, but not instantiated
  end Client_2;

  ----

  with Parent_Instance;
  with Parent.Child;
  package Client_3 is
    package I is new Parent_Instance.Child;
    -- Parent_Instance.Child is instantiated
  end Client_3;

Parent_Instance.Child declares a tagged type with two explicitly declared
homographic primitive operations, an apparent violation of 8.3(26/2). At
what point, if any, is this violation detected?

RM05 12.3(11) states that "In a generic unit Legality Rules are enforced
at compile time of the generic_declaration and generic body ..." .
When is that ?

Clearly Client_3 is rejected because Client_3.I violates the "no
dispatching homographs" rule, regardless of the treatment of
Parent_Instance.Child.

What about Client_2 and Client_1?

At one extreme, one could argue that a post-compilation check is required
in order to reject any partition whose closure includes both
Parent_Instance and Parent.Child, even if 10.1.1(19/2)'s conditions for
visibility are never met and the offending generic is never referenced.
This could only make sense if there was some burden associated with
 not doing this, perhaps a shared-code-generic implementation issue.

At the other extreme, one could argue that it is ok to omit Legality Rule
enforcement altogether in this case and accept Client_2 because
Parent_Instance.Child can never be successfully instantiated.

Any intermediate approach must also deal with the case where the offending
generic never meets 10.1.1(19/2)'s conditions for visibility but is
referenced via a sibling unit.

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

From: Edmond Schonberg
Date: Thursday, May 11, 2006  5:00 PM

> At what point, if any, are Legality Rules enforced for these
> declarations?

interesting question... My informal understanding was that sprouting
only happens right before cloning, i.e. when the child unit is going
to be instantiated. Otherwise this declaration has a rather ghostly
existence and no checks apply to it.  I don't see what would be
gained  by requiring legality checks on them, and in fact would find
it an annoying burden on the implementation.

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

From: Tucker Taft
Date: Thursday, May 11, 2006  8:20 PM

Good to see you haven't lost your touch... ;-)

In any case, I would say postpone any additional
legality checks until an instantiation of the child
takes place.  Anything else seems like useless extra work.
I suppose we should allow earlier detection, but
I would really hate to require it.

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

From: Randy Brukardt
Date: Friday, May 12, 2006  4:11 PM

> RM05 10.1.1(19/2) specifies the "sprouting" rules by which a child unit C
> of a parent generic package P causes the existence of a corresponding
> declaration nested immediately within each instance of P.
>
> At what point, if any, are Legality Rules enforced for these declarations?

I don't see anything in 12.3 talking about "sprouting". :-) It says that
legality rules are enforced when the generic spec and body are compiled, and
when the instance is compiled. It doesn't say anything about doing so at
other times as might be convinient to someone somewhere.

While there would be some benefit to allowing earlier detection in cases
like your examples, I have to think that writing the rules for that would be
very complex. (Heck, "sprouting" is very complex, and we've had to fix it
several times in the past.) And examples like these are going to be rare in
practice. Rare enough, I would think, that it wouldn't be worth it to
require early detection.

Moreover, there is some benefit to having consistent behavior (even if there
are cases where that behavior might be less friendly). Because of all of
that, I suggest that we leave the rules alone, and not even allow early
detection. (I believe the current rules are crystal-clear about that.)

...
> At one extreme, one could argue that a post-compilation check is required
> in order to reject any partition whose closure includes both
> Parent_Instance and Parent.Child, even if 10.1.1(19/2)'s conditions for
> visibility are never met and the offending generic is never referenced.
> This could only make sense if there was some burden associated with
>  not doing this, perhaps a shared-code-generic implementation issue.

Nope. A shared generic implementation is mostly likely going to compile the
(original) generic units in the normal way. Further processing would occur
only when it absolutely has to (at instantiation time) -- this legality
checking is pure overhead to us, and we're surely not going to do it unless
required by law. As far as the implementation of the instance goes, it would
be similar to an instance with a generic formal package, with the parent
instance passed in in the normal way -- so "sprouting" would have no effect
at all other than to define a new name that can be instantiated. Surely a
renames of such a name would have the same effect.

Allowing early checking would have no effect on us (surely we'd ignore it).
Requiring early checking would be a royal pain (*all* instantiation-time
checking is), and it would probably have to be all-new code (because the
"partialness" of it). Barf.

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


Questions? Ask the ACAA Technical Agent