* Loss of visibility of class-wide operation in prefix notation
@ 2014-04-05 15:09 Natasha Kerensikova
2014-04-07 15:30 ` Adam Beneschan
0 siblings, 1 reply; 2+ messages in thread
From: Natasha Kerensikova @ 2014-04-05 15:09 UTC (permalink / raw)
Hello,
I have been encountering some strange behavior of GNAT, and I wonder
whether it's a compiler bug or whether I'm doing something illegal.
Please consider the following code, it's a bit long but hopefully clear
enough:
package Root_Interface is
type T is interface;
procedure Process (Self : in out T; Result : out Boolean) is abstract;
procedure Process (Self : in out T'Class);
-- Call Process and discard Result
end Root_Interface;
package body Root_Interface is
procedure Process (Self : in out T'Class) is
Result : Boolean;
begin
Process (Self, Result);
end Process;
end Root_Interface;
package Root_Interface.Extension is
type T is interface and Root_Interface.T;
procedure Self_Check (Self : in out T) is abstract;
end Root_Interface.Extension;
with Root_Interface.Extension;
package Root_Interface.Half_Implementation is
type T is abstract new Extension.T with private;
not overriding procedure Subprocess (Self : in out T) is abstract;
overriding procedure Process (Self : in out T; Result : out Boolean);
overriding procedure Self_Check (Self : in out T);
type Example is new Extension.T with private;
private
type T is abstract new Extension.T with null record;
type Example is new T with record
Count : Natural := 0;
end record;
overriding procedure Subprocess (Self : in out Example);
end Root_Interface.Half_Implementation;
package body Root_Interface.Half_Implementation is
overriding procedure Process (Self : in out T; Result : out Boolean) is
begin
Subprocess (T'Class (Self));
Result := True;
end Process;
overriding procedure Self_Check (Self : in out T) is
begin
raise Program_Error;
end Self_Check;
overriding procedure Subprocess (Self : in out Example) is
begin
Self.Count := Self.Count + 1;
end Subprocess;
end Root_Interface.Half_Implementation;
package Root_Interface.Half_Implementation.Tests is
procedure Test_Suite;
end Root_Interface.Half_Implementation.Tests;
package body Root_Interface.Half_Implementation.Tests is
procedure Test_Suite is
Object : Example;
begin
Object.Process;
end Test_Suite;
end Root_Interface.Half_Implementation.Tests;
The basic idea is that I have a general root abstract type, used by most
clients of the library, with an optional extension. Then in a specific
of set of situations I can massively refactor the code, which leads to
the abstract "half-implementation", the other (mush smaller) half being
provided in concrete types by overriding the abstract primitive. In the
same package I also provide a basic concrete type, as an example to make
the code more self-documenting and to be used in the test suite.
The test suite itself is in a child package so that it can peek into the
implementation for whitebox tests.
So far everything is fine, and GNAT-AUX 4.9.0 compiles it happily.
But now I realize I need user-defined finalization in a concrete type
which inherits from Root_Interface.Half_Implementation.T, so I change it
to derive from Ada.Finalization.Controlled, without overriding anything:
with Ada.Finalization;
with Root_Interface.Extension;
package Root_Interface.Half_Implementation is
type T is abstract new Ada.Finalization.Controlled and Extension.T
with private;
not overriding procedure Subprocess (Self : in out T) is abstract;
overriding procedure Process (Self : in out T; Result : out Boolean);
overriding procedure Self_Check (Self : in out T);
type Example is new Extension.T with private;
private
type T is abstract new Ada.Finalization.Controlled and Extension.T
with null record;
type Example is new T with record
Count : Natural := 0;
end record;
overriding procedure Subprocess (Self : in out Example);
end Root_Interface.Half_Implementation;
And suddenly, GNAT rejects the test suite:
Compiling: root_interface-half_implementation-tests.adb
(source file time stamp: 2014-04-05 14:51:26)
6. Object.Process;
|
>>> missing argument for parameter "Result" in call to "Process"
ted) at root_interface-half_implementation.ads:15
However, when switching to traditional notation "Process (Object);"
everything is still fine. Moreover, when
Root_Interface.Half_Implementation.T implements Root_Interface.T rather
than the extension, everything still works fine.
Would you have any idea what I am doing wrong?
Thanks for your help,
Natasha
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Loss of visibility of class-wide operation in prefix notation
2014-04-05 15:09 Loss of visibility of class-wide operation in prefix notation Natasha Kerensikova
@ 2014-04-07 15:30 ` Adam Beneschan
0 siblings, 0 replies; 2+ messages in thread
From: Adam Beneschan @ 2014-04-07 15:30 UTC (permalink / raw)
On Saturday, April 5, 2014 8:09:07 AM UTC-7, Natasha Kerensikova wrote:
> Hello,
>
> I have been encountering some strange behavior of GNAT, and I wonder
> whether it's a compiler bug or whether I'm doing something illegal.
It appears to be a compiler bug. The "procedure Process (Self : in out T'Class)" should meet the requirements of 3.4.1(9.2) for "object.operation" notation. In any event, adding a new Ada.Finalization parent type shouldn't affect the legality (since Ada.Finalization does not have any primitive subprograms named Process).
-- Adam
>
>
>
> Please consider the following code, it's a bit long but hopefully clear
>
> enough:
>
>
>
>
>
> package Root_Interface is
>
>
>
> type T is interface;
>
>
>
> procedure Process (Self : in out T; Result : out Boolean) is abstract;
>
>
>
> procedure Process (Self : in out T'Class);
>
> -- Call Process and discard Result
>
>
>
> end Root_Interface;
>
>
>
>
>
> package body Root_Interface is
>
>
>
> procedure Process (Self : in out T'Class) is
>
> Result : Boolean;
>
> begin
>
> Process (Self, Result);
>
> end Process;
>
>
>
> end Root_Interface;
>
>
>
>
>
> package Root_Interface.Extension is
>
>
>
> type T is interface and Root_Interface.T;
>
>
>
> procedure Self_Check (Self : in out T) is abstract;
>
>
>
> end Root_Interface.Extension;
>
>
>
>
>
>
>
> with Root_Interface.Extension;
>
>
>
> package Root_Interface.Half_Implementation is
>
>
>
> type T is abstract new Extension.T with private;
>
>
>
> not overriding procedure Subprocess (Self : in out T) is abstract;
>
>
>
> overriding procedure Process (Self : in out T; Result : out Boolean);
>
> overriding procedure Self_Check (Self : in out T);
>
>
>
> type Example is new Extension.T with private;
>
>
>
> private
>
>
>
> type T is abstract new Extension.T with null record;
>
>
>
> type Example is new T with record
>
> Count : Natural := 0;
>
> end record;
>
>
>
> overriding procedure Subprocess (Self : in out Example);
>
>
>
> end Root_Interface.Half_Implementation;
>
>
>
>
>
> package body Root_Interface.Half_Implementation is
>
>
>
> overriding procedure Process (Self : in out T; Result : out Boolean) is
>
> begin
>
> Subprocess (T'Class (Self));
>
> Result := True;
>
> end Process;
>
>
>
>
>
> overriding procedure Self_Check (Self : in out T) is
>
> begin
>
> raise Program_Error;
>
> end Self_Check;
>
>
>
>
>
> overriding procedure Subprocess (Self : in out Example) is
>
> begin
>
> Self.Count := Self.Count + 1;
>
> end Subprocess;
>
>
>
> end Root_Interface.Half_Implementation;
>
>
>
>
>
> package Root_Interface.Half_Implementation.Tests is
>
>
>
> procedure Test_Suite;
>
>
>
> end Root_Interface.Half_Implementation.Tests;
>
>
>
>
>
> package body Root_Interface.Half_Implementation.Tests is
>
>
>
> procedure Test_Suite is
>
> Object : Example;
>
> begin
>
> Object.Process;
>
> end Test_Suite;
>
>
>
> end Root_Interface.Half_Implementation.Tests;
>
>
>
>
>
>
>
> The basic idea is that I have a general root abstract type, used by most
>
> clients of the library, with an optional extension. Then in a specific
>
> of set of situations I can massively refactor the code, which leads to
>
> the abstract "half-implementation", the other (mush smaller) half being
>
> provided in concrete types by overriding the abstract primitive. In the
>
> same package I also provide a basic concrete type, as an example to make
>
> the code more self-documenting and to be used in the test suite.
>
> The test suite itself is in a child package so that it can peek into the
>
> implementation for whitebox tests.
>
>
>
> So far everything is fine, and GNAT-AUX 4.9.0 compiles it happily.
>
>
>
> But now I realize I need user-defined finalization in a concrete type
>
> which inherits from Root_Interface.Half_Implementation.T, so I change it
>
> to derive from Ada.Finalization.Controlled, without overriding anything:
>
>
>
>
>
>
>
> with Ada.Finalization;
>
>
>
> with Root_Interface.Extension;
>
>
>
> package Root_Interface.Half_Implementation is
>
>
>
> type T is abstract new Ada.Finalization.Controlled and Extension.T
>
> with private;
>
>
>
> not overriding procedure Subprocess (Self : in out T) is abstract;
>
>
>
> overriding procedure Process (Self : in out T; Result : out Boolean);
>
> overriding procedure Self_Check (Self : in out T);
>
>
>
> type Example is new Extension.T with private;
>
>
>
> private
>
>
>
> type T is abstract new Ada.Finalization.Controlled and Extension.T
>
> with null record;
>
>
>
> type Example is new T with record
>
> Count : Natural := 0;
>
> end record;
>
>
>
> overriding procedure Subprocess (Self : in out Example);
>
>
>
> end Root_Interface.Half_Implementation;
>
>
>
>
>
>
>
> And suddenly, GNAT rejects the test suite:
>
> Compiling: root_interface-half_implementation-tests.adb
>
> (source file time stamp: 2014-04-05 14:51:26)
>
>
>
> 6. Object.Process;
>
> |
>
> >>> missing argument for parameter "Result" in call to "Process"
>
> ted) at root_interface-half_implementation.ads:15
>
>
>
>
>
> However, when switching to traditional notation "Process (Object);"
>
> everything is still fine. Moreover, when
>
> Root_Interface.Half_Implementation.T implements Root_Interface.T rather
>
> than the extension, everything still works fine.
>
>
>
>
>
> Would you have any idea what I am doing wrong?
>
>
>
>
>
>
>
> Thanks for your help,
>
> Natasha
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-04-07 15:30 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-05 15:09 Loss of visibility of class-wide operation in prefix notation Natasha Kerensikova
2014-04-07 15: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