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,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.236.69.74 with SMTP id m50mr15123004yhd.0.1396884605273; Mon, 07 Apr 2014 08:30:05 -0700 (PDT) X-Received: by 10.50.29.110 with SMTP id j14mr532501igh.5.1396884605155; Mon, 07 Apr 2014 08:30:05 -0700 (PDT) Path: border2.nntp.dca3.giganews.com!backlog4.nntp.dca3.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!m5no48257qaj.1!news-out.google.com!gi6ni228igc.0!nntp.google.com!l13no4000207iga.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Mon, 7 Apr 2014 08:30:04 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=66.126.103.122; posting-account=KSa2aQoAAACOxnC0usBJYX8NE3x3a1Xq NNTP-Posting-Host: 66.126.103.122 References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <7d18247e-28a3-4a4a-a246-36695819fe4c@googlegroups.com> Subject: Re: Loss of visibility of class-wide operation in prefix notation From: Adam Beneschan Injection-Date: Mon, 07 Apr 2014 15:30:05 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Original-Bytes: 7996 Xref: number.nntp.dca.giganews.com comp.lang.ada:185574 Date: 2014-04-07T08:30:04-07:00 List-Id: On Saturday, April 5, 2014 8:09:07 AM UTC-7, Natasha Kerensikova wrote: > Hello, >=20 > 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'C= lass)" should meet the requirements of 3.4.1(9.2) for "object.operation" no= tation. In any event, adding a new Ada.Finalization parent type shouldn't = affect the legality (since Ada.Finalization does not have any primitive sub= programs named Process).=20 -- Adam >=20 >=20 >=20 > Please consider the following code, it's a bit long but hopefully clear >=20 > enough: >=20 >=20 >=20 >=20 >=20 > package Root_Interface is >=20 >=20 >=20 > type T is interface; >=20 >=20 >=20 > procedure Process (Self : in out T; Result : out Boolean) is abstract; >=20 >=20 >=20 > procedure Process (Self : in out T'Class); >=20 > -- Call Process and discard Result >=20 >=20 >=20 > end Root_Interface; >=20 >=20 >=20 >=20 >=20 > package body Root_Interface is >=20 >=20 >=20 > procedure Process (Self : in out T'Class) is >=20 > Result : Boolean; >=20 > begin >=20 > Process (Self, Result); >=20 > end Process; >=20 >=20 >=20 > end Root_Interface; >=20 >=20 >=20 >=20 >=20 > package Root_Interface.Extension is >=20 >=20 >=20 > type T is interface and Root_Interface.T; >=20 >=20 >=20 > procedure Self_Check (Self : in out T) is abstract; >=20 >=20 >=20 > end Root_Interface.Extension; >=20 >=20 >=20 >=20 >=20 >=20 >=20 > with Root_Interface.Extension; >=20 >=20 >=20 > package Root_Interface.Half_Implementation is >=20 >=20 >=20 > type T is abstract new Extension.T with private; >=20 >=20 >=20 > not overriding procedure Subprocess (Self : in out T) is abstract; >=20 >=20 >=20 > overriding procedure Process (Self : in out T; Result : out Boolean); >=20 > overriding procedure Self_Check (Self : in out T); >=20 >=20 >=20 > type Example is new Extension.T with private; >=20 >=20 >=20 > private >=20 >=20 >=20 > type T is abstract new Extension.T with null record; >=20 >=20 >=20 > type Example is new T with record >=20 > Count : Natural :=3D 0; >=20 > end record; >=20 >=20 >=20 > overriding procedure Subprocess (Self : in out Example); >=20 >=20 >=20 > end Root_Interface.Half_Implementation; >=20 >=20 >=20 >=20 >=20 > package body Root_Interface.Half_Implementation is >=20 >=20 >=20 > overriding procedure Process (Self : in out T; Result : out Boolean) i= s >=20 > begin >=20 > Subprocess (T'Class (Self)); >=20 > Result :=3D True; >=20 > end Process; >=20 >=20 >=20 >=20 >=20 > overriding procedure Self_Check (Self : in out T) is >=20 > begin >=20 > raise Program_Error; >=20 > end Self_Check; >=20 >=20 >=20 >=20 >=20 > overriding procedure Subprocess (Self : in out Example) is >=20 > begin >=20 > Self.Count :=3D Self.Count + 1; >=20 > end Subprocess; >=20 >=20 >=20 > end Root_Interface.Half_Implementation; >=20 >=20 >=20 >=20 >=20 > package Root_Interface.Half_Implementation.Tests is >=20 >=20 >=20 > procedure Test_Suite; >=20 >=20 >=20 > end Root_Interface.Half_Implementation.Tests; >=20 >=20 >=20 >=20 >=20 > package body Root_Interface.Half_Implementation.Tests is >=20 >=20 >=20 > procedure Test_Suite is >=20 > Object : Example; >=20 > begin >=20 > Object.Process; >=20 > end Test_Suite; >=20 >=20 >=20 > end Root_Interface.Half_Implementation.Tests; >=20 >=20 >=20 >=20 >=20 >=20 >=20 > The basic idea is that I have a general root abstract type, used by most >=20 > clients of the library, with an optional extension. Then in a specific >=20 > of set of situations I can massively refactor the code, which leads to >=20 > the abstract "half-implementation", the other (mush smaller) half being >=20 > provided in concrete types by overriding the abstract primitive. In the >=20 > same package I also provide a basic concrete type, as an example to make >=20 > the code more self-documenting and to be used in the test suite. >=20 > The test suite itself is in a child package so that it can peek into the >=20 > implementation for whitebox tests. >=20 >=20 >=20 > So far everything is fine, and GNAT-AUX 4.9.0 compiles it happily. >=20 >=20 >=20 > But now I realize I need user-defined finalization in a concrete type >=20 > which inherits from Root_Interface.Half_Implementation.T, so I change it >=20 > to derive from Ada.Finalization.Controlled, without overriding anything: >=20 >=20 >=20 >=20 >=20 >=20 >=20 > with Ada.Finalization; >=20 >=20 >=20 > with Root_Interface.Extension; >=20 >=20 >=20 > package Root_Interface.Half_Implementation is >=20 >=20 >=20 > type T is abstract new Ada.Finalization.Controlled and Extension.T >=20 > with private; >=20 >=20 >=20 > not overriding procedure Subprocess (Self : in out T) is abstract; >=20 >=20 >=20 > overriding procedure Process (Self : in out T; Result : out Boolean); >=20 > overriding procedure Self_Check (Self : in out T); >=20 >=20 >=20 > type Example is new Extension.T with private; >=20 >=20 >=20 > private >=20 >=20 >=20 > type T is abstract new Ada.Finalization.Controlled and Extension.T >=20 > with null record; >=20 >=20 >=20 > type Example is new T with record >=20 > Count : Natural :=3D 0; >=20 > end record; >=20 >=20 >=20 > overriding procedure Subprocess (Self : in out Example); >=20 >=20 >=20 > end Root_Interface.Half_Implementation; >=20 >=20 >=20 >=20 >=20 >=20 >=20 > And suddenly, GNAT rejects the test suite: >=20 > Compiling: root_interface-half_implementation-tests.adb >=20 > (source file time stamp: 2014-04-05 14:51:26) >=20 >=20 >=20 > 6. Object.Process; >=20 > | >=20 > >>> missing argument for parameter "Result" in call to "Process" >=20 > ted) at root_interface-half_implementation.ads:15 >=20 >=20 >=20 >=20 >=20 > However, when switching to traditional notation "Process (Object);" >=20 > everything is still fine. Moreover, when >=20 > Root_Interface.Half_Implementation.T implements Root_Interface.T rather >=20 > than the extension, everything still works fine. >=20 >=20 >=20 >=20 >=20 > Would you have any idea what I am doing wrong? >=20 >=20 >=20 >=20 >=20 >=20 >=20 > Thanks for your help, >=20 > Natasha