Patrick Kelly
Patrick Kelly

Reputation: 603

Ada generic child instantiation claims to need itself

I have a generic package with the following signature

generic
    type T is private;
    with function "="(Left : T; Right : T) return Boolean is <>;
    with function Wide_Wide_Image(Self : T) return Wide_Wide_String is <>;
package Generics.Testing.Assertions is

It has a child package with the following signature

generic
    with function "<"(Left : T; Right : T) return Boolean is <>;
    with function ">"(Left : T; Right : T) return Boolean is <>;
package Generics.Testing.Assertions.Comparisons is

I'm trying to instantiate these inside of another package with an interesting problem.

This works fine:

package Integer_Assertions is new Generics.Testing.Assertions(
    Integer,
    Wide_Wide_Image => Integer'Wide_Wide_Image);

Where it gets weird is when I try to instantiate the child package with:

package Integer_Comparisons is new Integer_Assertions.Comparisons;

GPS finds the Comparisons package within Integer_Assertions just fine, as it should. But the compiler has the two following errors:

missing "with Integer_Assertions.Comparisons;"

and

"Comparisons" not declared in "Integer_Assertions"

Okay? But IntelliSense found it fine. I haven't done much Ada development in a while though, so maybe I'm forgetting how to instantiate a generic child of a generic.

So I try the fully qualified non-instance name instead:

package Integer_Comparisons is new Generics.Testing.Assertions.Comparison;

Which failed with:

invalid prefix in selected component "Generics.Testing.Assertions"

As I remember it should.

How do I actually instantiate the child inside of a package then?

Upvotes: 0

Views: 216

Answers (2)

Shark8
Shark8

Reputation: 4198

Oh, what's happening is that the dependency-graph isn't accurate, and the reason is that you need to with the deepest generic in the hierarchy. (eg with Generics.Testing.Assertions.Comparison;)

Then you do this:

package Integer_Assertions is new Generics.Testing.Assertions
  ( Integer, Wide_Wide_Image => Integer'Wide_Wide_Image );

package Integer_Comparisons is new Integer_Assertions.Comparisons;

The reason for this is that without with-ing the full dependency-path, the real dependency can't be found; this is the difference between nested- and hierarchical-package organization: you don't need to (and can't) with the nested units, you must with the deepest hierarchical unit(s) that you utilize.

Upvotes: 5

DeeDee
DeeDee

Reputation: 5941

I may be misinterpreting the question, but this compiles just fine in GNAT CE 2018:

with Generics.Testing.Assertions;
with Generics.Testing.Assertions.Comparisons;

procedure Main is

   package Integer_Assertions is
     new Generics.Testing.Assertions
       (Integer, Wide_Wide_Image => Integer'Wide_Wide_Image);

   package Integer_Comparisons is
     new Integer_Assertions.Comparisons;

begin
   null;
end Main;

Upvotes: 4

Related Questions