Version 1.1 of ais/ai-00086.txt

Unformatted version of ais/ai-00086.txt version 1.1
Other versions for file ais/ai-00086.txt

!standard 12.07(0) (00)          97-05-27 AI95-00086/03
!class confirmation 95-08-19
!status WG9 approved (8-0-0) 97-07-04
!status ARG approved (5-0-2) 97-04-11
!status work item 95-08-19
!status received 95-08-19
!priority Medium
!difficulty Hard
!subject Passing generic formal packages with (<>)
!summary 97-05-27
If a generic formal package B whose actual part is (<>) is passed as an actual to another generic formal package A without (<>), then 12.7(5-8) requires the actuals of B to match the actuals of A. For the purpose of this rule, the actuals of B are the entities denoted by names of the form B.x, where x is a generic formal parameter of B.
!question 97-05-27
If a generic formal package B whose actual part is (<>) is passed as an actual to another generic formal package A without (<>), then 12.7(5-8) requires the actuals of B to match the actuals of A. For the purpose of this rule, what are the actuals of B?
!response 97-05-27
12.7(5-8) require the actual parameters of the actual package to match the actual parameters of the formal package. But if the actual package has (<>), then its actual parameters are denoted by the formal parameters.
Consider the following illegal example:
generic type T is private; package Template is X : T; end Template;
with Template; generic type Ft1 is private; with package Formal_With_Actual is new Template( Ft1 ); package G1 is Y : Ft1 := Formal_With_Actual.X; end G1;
with Template; generic type Ft2 is private; with package Formal_With_Box is new Template( <> ); package G2 is package I3 is new G1( Ft2, Formal_With_Box ); -- Illegal! end G2;
The above is illegal, because the actual for Formal_With_Box is Formal_With_Box.T, and this does not statically match Ft2 (or anything else).
Note that if the above were legal, the following would cause trouble:
with Template, G2; package Instantiator is package I1 is new Template( Integer ); package I2 is new G2( Boolean, I1 ); end Instantiator;
because I2 contains a variable (Y) of type Boolean, initialized to I1.X, which is of type Integer.
Note that we cannot defer the check until instantiation time, because I3 could be in the body of G2 (instead of in the spec, as shown above), and this would constitute a contract model violation.
Now, consider the following legal example:
generic type T1 is private; package G1 is ... end G1;
generic type T2 is private; with package FP2 is new G1(T2); package G2 is ... end G2;
generic with package FP3 is new G1(<>); package G3 is package I2 is new G2(T2 => FP3.T1, FP2 => FP3); -- OK. ... end G3;
The instantiation I2 is legal because the actual for T2 is FP3.T1, which matches FP3.T1.
!appendix

!section 12.7(0)
!subject Generic Contract Model Violation ?
!reference AARM95-12.7;6.0
!from Jesper Joergensen 95-08-16
!reference as: 95-5257.a Jesper Joergensen 95-8-16>>
!discussion

The use of a formal package as an actual to another formal package is a quite
complex matter and as far as I can see we have a contract model violation with
the present rules. Consider the example (I'm sorry, but I don't think this
example can be shorter):


   -- first the "template" in the sense of [AARM 12.7(4)]:

   generic
      type T is private;
   package Template is
      X : T;
   end Template;


   -- then a formal package using the template:

   with Template;
   generic
      type Ft1 is private;
      with package Formal_With_Actual is new Template( Ft1 );
   package G1 is
      Y : Ft1 := Formal_With_Actual.X;
   end G1;


   -- then another formal package using the template:

   with Template;
   generic
      type Ft2 is private;
      with package Formal_With_Box is new Template( <> );
   package G2 is
      pragma Elaborate_Body;   -- just to make a body for G2 legal
   end G2;


   -- then a unit instantiating G2:

   with Template, G2;
   package Instantiator is
      package I1 is new Template( Integer );
      package I2 is new G2( Boolean, I1 );
   end Instantiator;


   -- so far nothing is wrong (all legality rules are fulfilled), but if the
   -- body of G2 contains an instantiation of G1 using its own formal
   -- parameters as the actuals, we have a problem:

   with G1;
   package body G2 is
      package I3 is new G1( Ft2, Formal_With_Box );
   end G2;

This is a legal instantiation as far as I can see. The result of all this is
that we have a package instance I2 with the following contents:

   package I2 is
      pragma Elaborate_Body;
   end I2;

   package body I2 is
      -- package I3 is new G1( Boolean, I1 ):
      package I3 is
         Y : Boolean := I1.X;
      end I3;
   end I2;


And here we have a boolean variable initialized to that of an integer value!
because we have associated the formal type T with both of these types.

1. Is the above analysis correct ?
2. If yes, don't we need a legality rule that forbids using a formal package
   with a box as an actual package for a formal package without box. As far as
   I can see this kind of instantiation is the only one requiring an extra
   check in an instance (for an enclosed instance) for the rules 12.7(6-8).
   In all other cases we only need to check for these rules at the place of
   the individual instantiations. In the context of the above example, we
   can't check the rules at the place of G2.I3 because we still don't know
   the actuals for Formal_With_Box.


/Jesper, DDC-I

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

!section 12.7(00)
!subject Generic Contract Model Violation ?
!reference AARM95-12.7;6.0
!reference 95-5257.a Jesper Joergensen 95-08-16
!from Tucker Taft 95-08-16
!reference as: 95-5260.a Tucker Taft 95-8-17>>
!discussion

> The use of a formal package as an actual to another formal package is a quite
> complex matter and as far as I can see we have a contract model violation with
> the present rules. Consider the example (I'm sorry, but I don't think this
> example can be shorter):
> 
> 
>    -- first the "template" in the sense of [AARM 12.7(4)]:
> 
>    generic
>       type T is private;
>    package Template is
>       X : T;
>    end Template;
> 
> 
>    -- then a formal package using the template:
> 
>    with Template;
>    generic
>       type Ft1 is private;
>       with package Formal_With_Actual is new Template( Ft1 );
>    package G1 is
>       Y : Ft1 := Formal_With_Actual.X;
>    end G1;
> 
> 
>    -- then another formal package using the template:
> 
>    with Template;
>    generic
>       type Ft2 is private;
>       with package Formal_With_Box is new Template( <> );
>    package G2 is
>       pragma Elaborate_Body;   -- just to make a body for G2 legal
>    end G2;
> 
> 
>    -- then a unit instantiating G2:
> 
>    with Template, G2;
>    package Instantiator is
>       package I1 is new Template( Integer );
>       package I2 is new G2( Boolean, I1 );
>    end Instantiator;
> 
> 
>    -- so far nothing is wrong (all legality rules are fulfilled), but if the
>    -- body of G2 contains an instantiation of G1 using its own formal
>    -- parameters as the actuals, we have a problem:
> 
>    with G1;
>    package body G2 is
>       package I3 is new G1( Ft2, Formal_With_Box );

This violates 12.7(5), since the actual parameter of the 
"instance" Formal_With_Box is Formal_With_Box.T, and this does not
statically match Ft2.

>    end G2;
> 
> This is a legal instantiation as far as I can see. 

No, it violates 12.7(5).  When inside a generic, a 
formal-package-with-box F looks like an instance whose
actual parameters are F.formal1, F.formal2, etc.
These "actual" parameters only match themselves for the purposes
of 12.7(6..8), since nothing else is known about them.

Perhaps an explicit clarification of this in the RM would be helpful.

> ...
> 1. Is the above analysis correct ?

No.

> ...
> /Jesper, DDC-I

-Tuck

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

!section 12.7(00)
!subject Generic Contract Model Violation ?
!reference AARM95-12.7;6.0
!reference 95-5257.a Jesper Joergensen 95-8-16
!from Jesper Joergensen 95-08-16
!reference as: 95-5261.a Pascal Leroy 95-8-17>>
!discussion

>    -- first the "template" in the sense of [AARM 12.7(4)]:
>
>    generic
>       type T is private;
>    package Template is
>       X : T;
>    end Template;
>
>    -- then a formal package using the template:
>
>    with Template;
>    generic
>       type Ft1 is private;
>       with package Formal_With_Actual is new Template( Ft1 );
>    package G1 is
>       Y : Ft1 := Formal_With_Actual.X;
>    end G1;
>
>    -- then another formal package using the template:
>
>    with Template;
>    generic
>       type Ft2 is private;
>       with package Formal_With_Box is new Template( <> );
>    package G2 is
>       pragma Elaborate_Body;   -- just to make a body for G2 legal
>    end G2;
>
>    -- so far nothing is wrong (all legality rules are fulfilled), but if the
>    -- body of G2 contains an instantiation of G1 using its own formal
>    -- parameters as the actuals, we have a problem:
>
>    with G1;
>    package body G2 is
>       package I3 is new G1( Ft2, Formal_With_Box );
>    end G2;
>
> This is a legal instantiation as far as I can see. The result of all this is
> that we have a package instance I2 with the following contents:

I may have an overly optimistic reading of the RM, but this instantiation
seems illegal to me.  RM95 12.7(5) states that "each actual parameter of the
actual instance shall match the corresponding actual parameter of the formal
package". In addition, RM95 12.3(3-4) indicates that actual parameters are
provided by a generic_actual_part.  Now the syntax in RM95 12.7(3) clearly
says that "(<>)" is _not_ a generic_actual_part.

>From these rules I draw the conclusion that your Formal_With_Box has no actual
parameters, and therefore that the instantiation I3 is illegal, because the
actual parameters don't match the formal parameters.

Note that following this reasoning, I3 would be legal if Template had an empty
generic_formal_part: Formal_With_Actual would have an empty
generic_actual_part, and in this case the actual parameters of Formal_With_Box
would match those of Formal_With_Actual.  But I don't see that you could come
up with a contract model violation with empty formal parts...

> 1. Is the above analysis correct ?
> 2. If yes, don't we need a legality rule that forbids using a formal package
>    with a box as an actual package for a formal package without box. As far
as
>    I can see this kind of instantiation is the only one requiring an extra
>    check in an instance (for an enclosed instance) for the rules 12.7(6-8).
>    In all other cases we only need to check for these rules at the place of
>    the individual instantiations. In the context of the above example, we
>    can't check the rules at the place of G2.I3 because we still don't know
>    the actuals for Formal_With_Box.

Even if your analysis was correct (which I doubt), it would not be a good idea
to do the check in the instance.  If we want to avoid all sorts of nasty
dependences on the contents of the generic bodies, the check must be done at
the place of G2.I3, "assuming the worst" (as is already the case for other
rules).

Pascal.

_____________________________________________________________________
Pascal Leroy                                    +33.1.30.12.09.68
pleroy@rational.com                             +33.1.30.12.09.66 FAX

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

Questions? Ask the ACAA Technical Agent