Question on the 'use all type' clause

Hello all.

I started my career as an ADA developer twenty-ish years ago. These days I’m reading John Barnes’ book as I want to go back to doing some ADA stuff at home (and why not at work).

I hope it’s okay to post a perhaps basic question here. I did search the web but that didn’t answer my question.

There’s one concept that I cannot wrap my head around: what subprograms exactly become directly visible if I use the ‘use all type’ clause.
The book says : “This makes directly visible all the operations of a type and not just those denoted by operators.” I think it really means, all the primitive operations. But what’s that?

For example I’m playing with the Game of Life example he gives in the book. I’ve implemented my own version (work in progress) on Github here: LINK

What I don’t understand is that if in the main program I add the clause:

use all type P_Board.T_Board;

after the declaration of package P_Board, I can then write:

My_Board : constant P_Board.T_Board := Get_Empty_Board;

instead of:

My_Board : constant P_Board.T_Board := P_Board.Get_Empty_Board;

But if I write the following:

Set_Cell_Alive (My_Board, 5, 6);

instead of:

P_Board.Set_Cell_Alive (My_Board, 5, 6);

It says:

error: “Set_Cell_Alive” is not visible

I find it strange because Set_Cell_Alive is defined in the same package as the type T_Board so should it not work?

I feel like it may be a bug that Set_Cell_Alive isn’t visible, but I am not a language lawyer. I think the pertinent section is:

http://www.ada-auth.org/standards/22rm/html/RM-8-4.html#I4272

I think the operation is primitive, so it should be visible. So maybe a bug, but perhaps someone with more experience will know for sure.

Thanks!

I hope the problem is not in front of the computer because I haven’t read the chapter on Generics yet, so I am using them as I remember them from years ago.

Anyway, I have made a sample program which illustrates my question better:

with Ada.Text_IO; use Ada.Text_IO;

procedure Test_Use_Type is

   package Not_Generic is
      type TA is private;
      function F_TA return TA;
      procedure P_TA (A : TA);
   private
      type TA is new Integer;
   end Not_Generic;
   package body Not_Generic is
      function F_TA return TA is
      begin
         return 1;
      end F_TA;
      procedure P_TA (A : TA) is
      begin
         Put_Line (A'Image);
      end P_TA;
   end Not_Generic;

   generic
      TG : Integer;
   package Generic_Package is
      type TB is private;
      function F_TB return TB;
      procedure P_TB (B : TB);
   private
      type TB is new Integer range 1 .. TG;
   end Generic_Package;
   package body Generic_Package is
      function F_TB return TB is
      begin
         return 1;
      end F_TB;
      procedure P_TB (B : TB) is
      begin
         Put_Line (B'Image);
      end P_TB;
   end Generic_Package;

   use all type Not_Generic.TA;
   package Generic_1 is new Generic_Package (10);
   use all type Generic_1.TB;
   package Generic_2 is new Generic_Package (10);
   use all type Generic_2.TB;

   My_A  : Not_Generic.TA;
   My_B1 : Generic_1.TB := F_TB;  --  (1)
   My_B2 : Generic_2.TB;

begin
   My_A := F_TA;  --  (2)
   P_TA (My_A);   --  (3)
   P_TB (My_B1);  --  (4)
   My_B2 := F_TB; --  (5)
   P_TB (My_B2);  --  (6)
end Test_Use_Type;

The compilation fails:

test_use_type.adb:56:04: error: "P_TB" is not visible (more references follow)
test_use_type.adb:56:04: error: non-visible declaration from "Generic_2" at line 28, instance at line 46
test_use_type.adb:56:04: error: non-visible declaration from "Generic_1" at line 28, instance at line 44
test_use_type.adb:57:13: error: "F_TB" is not visible
test_use_type.adb:57:13: error: non-visible declaration from "Generic_2" at line 27, instance at line 46
test_use_type.adb:57:13: error: non-visible declaration from "Generic_1" at line 27, instance at line 44

So this means that when the package is not generic, I can use the primitive subprograms just like I expect. See (2) and (3).
When the package is generic and I create an instance of it in the declarative part of a block, I can use the function in the same declarative part. See (1).
But the exact same function cannot be used after the ‘begin’. See (5).
And procedures after the ‘begin’ also don’t work. See (4) and (6).

I find it strange.

Edit : (GNAT 14.2.1)