I try to compile an Ada 95 program with an Ada 2012 compiler. However there are problems with instantiation of the generic package Garbage_Collector
. The subtype A_Term
is not accepted in the package instantiation:
prolog.adb:27:15: designated type of actual does not match that of formal "Link"
prolog.adb:27:15: instantiation abandoned
I have tried to change A_Term
to type A_Term is access A_Node;
. Then the package will instantiate, but the rest of the code breaks. Has something changed since Ada 95 and how can I make it work in Ada 2012?
procedure Prolog is
generic
type Item is limited private;
type Link is access Item;
package Garbage_Collector is
procedure Get (L : in out Link) is null;
end Garbage_Collector;
type Node_Tag is (A, B);
type Node (Tag : Node_Tag);
type Term is access Node;
type Node (Tag : Node_Tag) is
record
case Tag is
when A => null;
when B => null;
end case;
end record;
subtype A_Node is Node (A);
subtype A_Term is Term (A);
package Gc_A is new Garbage_Collector
(Item => A_Node,
Link => A_Term);
T : Term;
begin
Gc_A.Get (T);
end Prolog;
The code is from a Prolog module from Stanford University. The project on GitHub
I can't say what exactly causes your error. It could well be that this is a compiler bug. To fix this in a minimal invasive way, I suggest to make the access
relation invisible to the generic unit:
procedure Prolog is
generic
type Item is limited private;
type Link is private;
with function Deref (L : Link) return Item is <>;
package Garbage_Collector is
procedure Get (L : in out Link) is null;
end Garbage_Collector;
type Node_Tag is (A, B);
type Node (Tag : Node_Tag);
type Term is access Node;
type Node (Tag : Node_Tag) is
record
case Tag is
when A => null;
when B => null;
end case;
end record;
subtype A_Node is Node (A);
subtype A_Term is Term (A);
function Deref (L : A_Term) return A_Node is (L.all);
package Gc_A is new Garbage_Collector
(Item => A_Node,
Link => A_Term);
T : Term;
begin
Gc_A.Get (T);
end Prolog;
Now the compiler does not complain because the formal type Link
is not an access type anymore and has no relation to Item
. By giving the function Deref
, you are still able to dereference an object of type Link
. You will need an additional function if you need to assign to it.
In your code sample above, you declare types Node
and Term
:
type Node (Tag : Node_Tag);
type Term is access Node;
You then attempt to declare two subtypes:
subtype A_Node is Node (A);
subtype A_Term is Term (A);
The declaration of subtype A_Node
makes sense, since Node
is a discriminant type. The declaration of subtype A_Term
does not make sense. Type Term
is access Node
, which is different from type Node
. Try changing the declaration of subtype A_Term
to:
subtype A_Term is access A_Node;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With