From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Natasha Kerensikova Newsgroups: comp.lang.ada Subject: Loss of visibility of class-wide operation in prefix notation Date: Sat, 5 Apr 2014 15:09:07 +0000 (UTC) Organization: A noiseless patient Spider Message-ID: Injection-Date: Sat, 5 Apr 2014 15:09:07 +0000 (UTC) Injection-Info: mx05.eternal-september.org; posting-host="76a49b86bc3e16725b7cfca3d85cb4c8"; logging-data="5947"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19aUtIXL3Gow9yIRwhxneaZ" User-Agent: slrn/1.0.1 (FreeBSD) Cancel-Lock: sha1:Vhb/WMgBARCZAkjrA+8lesatOJQ= Xref: news.eternal-september.org comp.lang.ada:19170 Date: 2014-04-05T15:09:07+00:00 List-Id: 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