comp.lang.ada
 help / color / mirror / Atom feed
* Another compiler problem related to multiple inheritance?
@ 2008-04-11  7:33 Maciej Sobczak
  2008-04-11 16:30 ` Adam Beneschan
  0 siblings, 1 reply; 2+ messages in thread
From: Maciej Sobczak @ 2008-04-11  7:33 UTC (permalink / raw)


Consider the following:

-- types.ads:
generic
   type T is private;
package Types is

   type Base is interface;

   function "=" (Left : Base;
                 Right : Base) return Boolean is abstract;

   -- Note: diamond-shaped hierarchy:

   type Middle_1 is interface and Base;
   type Middle_2 is interface and Base;
   type Middle   is interface and Middle_1 and Middle_2;

end Types;

-- types-concrete_types.ads:
generic
package Types.Concrete_Types is

   type Concrete is new Middle with null record;

   overriding
   function "=" (Left : Concrete; Right : Concrete) return Boolean;

end Types.Concrete_Types;

-- types-concrete_types.adb:
package body Types.Concrete_Types is
   function "=" (Left : Concrete;
                 Right : Concrete) return Boolean is
   begin
      return True;
   end "=";
end Types.Concrete_Types;

-- processing.ads:
with Types;
package Processing is

   generic
      type Element_Type is private;
      with package Some_Types is new Types (T => Element_Type);
      type Middle_1_Type (<>) is new Some_Types.Middle_1 with private;
      type Middle_2_Type (<>) is new Some_Types.Middle_2 with private;
   procedure Do_Something (A : in Middle_1_Type;
                           B : in Middle_2_Type);

end Processing;

-- processing.adb:
package body Processing is

   procedure Do_Something (A : in Middle_1_Type;
                           B : in Middle_2_Type) is
   begin
      null;
   end Do_Something;

end Processing;

-- main.adb:
with Types.Concrete_Types;
with Processing;
procedure Main is

   package My_Types is new Types (T => Integer);
   package My_Concrete_Types is new My_Types.Concrete_Types;

   use My_Concrete_Types;

   procedure My_Do_Something is new Processing.Do_Something
     (Element_Type => Integer,
      Some_Types => My_Types,
      Middle_1_Type => Concrete,
      Middle_2_Type => Concrete); -- here is the problem

begin
   null;
end Main;

To sum it up: there is a diamond-shaped interface hierarchy. The
Concrete type derives indirectly from both Middle_1 and Middle_2.
The instantiation of Do_Something in Main fails at the point marked
above with the following:

$ gnatmake main
gcc -c main.adb
main.adb:14:24: (Ada 2005) expected type implementing "Middle_2" in
instantiation
gnatmake: "main.adb" compilation error
$

This error message is misleading, because obviously Concrete
implements Middle_2 (just as it implements Middle_1 - this is
symmetric).

An interesting part is that after removing function "=" from the Base
interface, everything compiles fine, which brings more questions:

1. How is it possible that function "=" in Concrete compiled? It is
marked as overriding. What it is overriding? The default comparison
operation?

2. How does it influence the ability of the compiler to verify that
Concrete implements Middle_2?

3. Is function "=" in Base correct anyway? Will it dispatch properly
when calling via class-wide Base'Class (assuming that Left and Right
always have the same tag)?

In any case, the compiler error might indicate the problem related to
what I've found previously - that multiple inheritance of interfaces
is not (yet) properly supported.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Another compiler problem related to multiple inheritance?
  2008-04-11  7:33 Another compiler problem related to multiple inheritance? Maciej Sobczak
@ 2008-04-11 16:30 ` Adam Beneschan
  0 siblings, 0 replies; 2+ messages in thread
From: Adam Beneschan @ 2008-04-11 16:30 UTC (permalink / raw)


On Apr 11, 12:33 am, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> Consider the following:
>
> -- types.ads:
> generic
>    type T is private;
> package Types is
>
>    type Base is interface;
>
>    function "=" (Left : Base;
>                  Right : Base) return Boolean is abstract;
>
>    -- Note: diamond-shaped hierarchy:
>
>    type Middle_1 is interface and Base;
>    type Middle_2 is interface and Base;
>    type Middle   is interface and Middle_1 and Middle_2;
>
> end Types;
>
> -- types-concrete_types.ads:
> generic
> package Types.Concrete_Types is
>
>    type Concrete is new Middle with null record;
>
>    overriding
>    function "=" (Left : Concrete; Right : Concrete) return Boolean;
>
> end Types.Concrete_Types;
>
> -- types-concrete_types.adb:
> package body Types.Concrete_Types is
>    function "=" (Left : Concrete;
>                  Right : Concrete) return Boolean is
>    begin
>       return True;
>    end "=";
> end Types.Concrete_Types;
>
> -- processing.ads:
> with Types;
> package Processing is
>
>    generic
>       type Element_Type is private;
>       with package Some_Types is new Types (T => Element_Type);
>       type Middle_1_Type (<>) is new Some_Types.Middle_1 with private;
>       type Middle_2_Type (<>) is new Some_Types.Middle_2 with private;
>    procedure Do_Something (A : in Middle_1_Type;
>                            B : in Middle_2_Type);
>
> end Processing;
>
> -- processing.adb:
> package body Processing is
>
>    procedure Do_Something (A : in Middle_1_Type;
>                            B : in Middle_2_Type) is
>    begin
>       null;
>    end Do_Something;
>
> end Processing;
>
> -- main.adb:
> with Types.Concrete_Types;
> with Processing;
> procedure Main is
>
>    package My_Types is new Types (T => Integer);
>    package My_Concrete_Types is new My_Types.Concrete_Types;
>
>    use My_Concrete_Types;
>
>    procedure My_Do_Something is new Processing.Do_Something
>      (Element_Type => Integer,
>       Some_Types => My_Types,
>       Middle_1_Type => Concrete,
>       Middle_2_Type => Concrete); -- here is the problem
>
> begin
>    null;
> end Main;
>
> To sum it up: there is a diamond-shaped interface hierarchy. The
> Concrete type derives indirectly from both Middle_1 and Middle_2.
> The instantiation of Do_Something in Main fails at the point marked
> above with the following:
>
> $ gnatmake main
> gcc -c main.adb
> main.adb:14:24: (Ada 2005) expected type implementing "Middle_2" in
> instantiation
> gnatmake: "main.adb" compilation error
> $
>
> This error message is misleading, because obviously Concrete
> implements Middle_2 (just as it implements Middle_1 - this is
> symmetric).
>
> An interesting part is that after removing function "=" from the Base
> interface, everything compiles fine, which brings more questions:
>
> 1. How is it possible that function "=" in Concrete compiled? It is
> marked as overriding. What it is overriding? The default comparison
> operation?

Yes.  (The language refers to it as the "predefined" equality
operator, rather than "default".)  The language rules say that this
operator must be overridden for Concrete, because the operation of the
parent type is abstract.


> 2. How does it influence the ability of the compiler to verify that
> Concrete implements Middle_2?

One would have to look at the compiler source to answer that.  This
looks like just a bug.  The compiler doesn't do things right in that
particular case.


> 3. Is function "=" in Base correct anyway? Will it dispatch properly
> when calling via class-wide Base'Class (assuming that Left and Right
> always have the same tag)?

Yes.

                                -- Adam



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-04-11 16:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-04-11  7:33 Another compiler problem related to multiple inheritance? Maciej Sobczak
2008-04-11 16:30 ` Adam Beneschan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox