Version 1.1 of acs/ac-00322.txt

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

!standard 12.7(10/2)          20-01-14 AC95-00322/00
!class confirmation 20-01-14
!status received no action 20-01-14
!status received 19-11-14
!subject Generic signature package subprogram visibility

From: Vincent Marcante
Sent: Thursday, November 14, 2019  9:35 AM

Object Ada and GNAT respond differently to the code that appears at the end of 
this message. Object Ada compiles and runs it as expected but GNAT indicates
“no visible subprogram matches the specification for "Put" “ at the 
definition of package Signature_Package_Reexport_Instance
A c.l.a commenter indicated that he had had this problem forever too, but was 
told by the GNAT and Ada experts that this was actually expected behavior - 
something to do with whether the user of the generic instance can see what the 
actual parameters were. So if you pass the signature package as a parameter 
in the instantiation of another generic, then you can reference the formal 
parameters, but if the compiler see statically what the actual parameters 
are, you cannot. This is a pain point when using generics.

One workaround is to put a rename declaration in the generic “signature” 
package: but this is a pain because we have to invent a second name to 
designated the same thing.
So, should all of the following be compilable?  

If the standard in fact requires disallowance, I wonder what "bad" thing is
being prevented/avoided by not allowing the naturally expected, non-painful
behavior.  Might changing the standard to allow it - or be clear that it is 
allowed - be warranted?

with Ada.Text_IO;
package Ada_Text_IO_Adaptor is
  procedure Put
           (X    : in Integer;
            Base : in Ada.Text_IO.Number_Base);
  procedure New_Line;
end Ada_Text_IO_Adaptor;
with Ada.Integer_Text_IO;
package body Ada_Text_IO_Adaptor is
  procedure Put
           (X    : in Integer;
            Base : in Ada.Text_IO.Number_Base) is
  end Put;
  procedure New_Line is
  end New_Line;
end Ada_Text_IO_Adaptor;
  type Number_Base is range <>;
  Default_Base : Number_Base;
  with procedure Put      (X    : in Integer;
                           Base : in Number_Base
                                  := Default_Base) is <>;
  with procedure Put      (X    : in String) is <>;
  with procedure Put_Line (X    : in String) is <>;
  with procedure New_Line is <>;
package Signature_Package_Generic is end;
with Ada.Text_IO, Ada.Integer_Text_IO, Ada_Text_IO_Adaptor;
 use Ada.Text_IO, Ada.Integer_Text_IO, Ada_Text_IO_Adaptor;
with Signature_Package_Generic;
package Signature_Package_Instance is
    new Signature_Package_Generic
                         (Number_Base  => Ada.Text_IO.Number_Base,
                          Default_Base => 10);
with Signature_Package_Generic;
  with package Instance is new Signature_Package_Generic(<>);
procedure Signature_Package_Instance_Test_Generic;
procedure Signature_Package_Instance_Test_Generic is
  Instance.Put_Line("Direct Instance Put_Line(""string"")");
  Instance.Put     ("Direct Instance Put     (""string"")");
with      Signature_Package_Instance;
with      Signature_Package_Instance_Test_Generic;
procedure Signature_Package_Instance_Test is
      new Signature_Package_Instance_Test_Generic
         (Signature_Package_Instance); --compiles and runs as expected (Put is visible)
with Signature_Package_Generic;
  with package Instance is new Signature_Package_Generic(<>);
package Signature_Package_Reexport_Generic is
  subtype Number_Base is Instance.Number_Base;
  Default_Base : Number_Base := Instance.Default_Base;
  procedure Put      (X    : in Integer;
                      Base : in Number_Base
                             := Default_Base) renames Instance. Put;
  procedure Put      (X    : in String)       renames Instance. Put; -- instantiation error
  procedure Put_Line (X    : in String)       renames Instance. Put_Line;
  procedure New_Line                          renames Instance. New_Line;
end Signature_Package_Reexport_Generic;
with    Signature_Package_Instance;
with    Signature_Package_Reexport_Generic;
package Signature_Package_Reexport_Instance is
    new Signature_Package_Reexport_Generic
--Builder results
--        108:1 instantiation error at
--        108:1 no visible subprogram matches the specification for "Put"
with      Signature_Package_Reexport_Instance;
procedure Signature_Package_Reexport_Test is
  Signature_Package_Reexport_Instance.Put_Line("Reexport Put_Line(""string"")");
  Signature_Package_Reexport_Instance.Put     ("Reexport Put     (""string"")");

From: Tucker Taft
Sent: Thursday, November 14, 2019  3:07 PM

This looks like a GNAT bug.  If the formal package has (<>) as its actual 
parameter part, then all of the formal parameters are visible in the visible 
part of the formal package.  If some of the actual parameters are specified 
in the declaration of the formal package, then the formal corresponding to 
those actuals are *not* visible.  The general rule is either the actual or 
the formal is visible, but never both.  But in this example, the actual 
parameter part is (<>), so all of the formals are visible.  Below is the 
relevant section of the (annotated) Ada RM (12.7(10-10.b)).

10/2 {AI95-00317-01} The visible part of a formal package includes the first 
list of basic_declarative_items of the package_specification. In addition, 
for each actual parameter that is not required to match, a copy of the 
declaration of the corresponding formal parameter of the template is included 
in the visible part of the formal package. If the copied declaration is for a 
formal type, copies of the implicit declarations of the primitive subprograms 
of the formal type are also included in the visible part of the formal package.

10.a/2 Ramification: {AI95-00317-01} If the formal_package_actual_part is (<>), 
then the declarations that occur immediately within the generic_formal_part of 
the template for the formal package are visible outside the formal package, 
and can be denoted by expanded names outside the formal package. If only some 
of the actual parameters are given by <>, then the declaration corresponding 
to those parameters (but not the others) are made visible.

10.b/3 Reason: {AI05-0005-1} We always want either the actuals or the formals 
of an instance to be nameable from outside, but never both. If both were 
nameable, one would get some funny anomalies since they denote the same 
entity, but, in the case of types at least, they might have different and 
inconsistent sets of primitive operators due to predefined operator 
“reemergence.” Formal derived types exacerbate the difference. We want the 
implicit declarations of the generic_formal_part as well as the explicit 
declarations, so we get operations on the formal types. 


From: Vincent Marciante
Sent: Friday, November 15, 2019  7:08 AM

Thankyou for your very quick response.

May I quote this to comp.lang.ada?

Noting your email address, may I assume that  Adacore is now aware of this issue
or must I also sent a report to “GNAT bugs” email address?


From: Tucker Taft
Sent: Friday, November 15, 2019  3:27 PM

You may quote me on comp.lang.ada, but as an individual.  I don't "officially" 
speak for AdaCore ;-)

Also, if you could, please report the bug yourself, with a simple, compilable 
"reproducer."  This ensures that the bug report gets properly logged into our 
tracking system.


From: Randy Brukardt
Sent: Tuesday, July 2, 2019  10:17 PM


Questions? Ask the ACAA Technical Agent