Version 1.3 of ai05s/ai05-0128-1.txt
!standard 3.2.3(6) 09-02-15 AI05-0128-1/01
!class binding interpretation 08-10-17
!status work item 08-10-17
!status received 08-08-22
!priority Low
!difficulty Medium
!qualifier Omission
!subject "/=" is a primitive operation
!summary
"/=" is a primtive operation for the purposes of a use type clause.
!question
Consider:
package Pack1 is
type Rec is limited record
F1 : Integer;
end record;
function "=" (Left, Right : Rec) return Boolean;
end Pack1;
package body Pack1 is
function "=" (Left, Right : Rec) return Boolean is
begin
return abs(Left.F1) = abs(Right.F1);
end "=";
end Pack1;
with Pack1;
package Pack2 is
procedure Proc (X, Y : Pack1.Rec);
end Pack2;
package body Pack2 is
procedure Proc (X, Y : Pack1.Rec) is
B : Boolean;
use type Pack1.Rec;
begin
B := (X = Y); --
B := (X /= Y); --
end Proc;
end Pack2;
It would be surprising if the "use type" caused "=" to become visible
but not "/=". But the language rules appear to state that.
USE TYPE makes primitive operators visible. 3.2.3(6)
says that "=" is a primitive subprogram and therefore a primitive operator.
But there is nothing in 3.2.3(2-7) that makes the implicitly
declared "/=" primitive. 3.2.3(3) refers to "predefined operators", not
implicitly declared operators, and it also refers to section 4.5; and
4.5.2(1) says that "=" and "/=" are predefined for nonlimited types only.
Also, 6.6(6) calls the "/=" function implicitly declared, not "predefined".
Since "/=" is not explicitly declared, the other bullet points in
3.2.3(4-7) don't apply.
Is "/=" made visible by USE TYPE? (Yes.)
!recommendation
(See Summary.)
Add after RM 3.2.3(6):
* For a specific type with an explicitly-declared primitive "="
operator whose result type is Boolean, the corresponding "/=" operator
(see 6.6);
!discussion
Adding a bullet to 3.2.3 seems the simplest way to include the implicitly
declared "/=" operator produced when an "=" is explicitly declared.
We originally considered simply eliminating the word "explicitly" from
3.2.3(6), and thereby including the implicitly declared "/=". That also
would have included, redundantly, the inherited subprograms and
predefined operators, but that seemed OK. The only real concern was
that we might include implicitly declared subprograms that we did not
want to consider primitive. Unfortunately, there are such cases. In
particular, in the following example, an implicitly declared operation
that operates on type B is not a primitive of B:
package P is
type A is (dummy);
type B is (nothing);
procedure Prim(X : A; Y : B);
type C is new A;
--
--
--
end P;
--!corrigendum 3.2.3(6)
!ACATS Test
An ACATS B-Test like the example in the question is needed.
!appendix
!topic /= is not primitive?
!reference RM05 3.2.3(2-7), 4.5.2(1), 6.6(6)
!from Adam Beneschan 08-10-23
!discussion
In this example:
package Pack1 is
type Rec is limited record
F1 : Integer;
end record;
function "=" (Left, Right : Rec) return Boolean;
end Pack1;
package body Pack1 is
function "=" (Left, Right : Rec) return Boolean is
begin
return abs(Left.F1) = abs(Right.F1);
end "=";
end Pack1;
with Pack1;
package Pack2 is
procedure Proc (X, Y : Pack1.Rec);
end Pack2;
package body Pack2 is
procedure Proc (X, Y : Pack1.Rec) is
B : Boolean;
use type Pack1.Rec;
begin
B := (X = Y); -- LEGAL
B := (X /= Y); -- ILLEGAL?
end Proc;
end Pack2;
It would be surprising if the "use type" caused "=" to become visible
but not "/=". But that's what I think is happening, according to the
language rules. USE TYPE makes primitive operators visible. 3.2.3(6)
says that "=" is a primitive subprogram and therefore a primitive operator.
But I can't find a bullet point in 3.2.3(2-7) that makes the implicitly
declared "/=" primitive. 3.2.3(3) refers to "predefined operators", not
implicitly declared operators, and it also refers to section 4.5; and
4.5.2(1) says that "=" and "/=" are predefined for nonlimited types only.
Also, 6.6(6) calls the "/=" function implicitly declared, not "predefined".
Since "/=" is not explicitly declared, the other bullet points in
3.2.3(4-7) don't apply.
My suggestion: Add another bullet point after 3.2.3(7):
* An implicitly declared "/=", if the "=" subprogram whose declaration
leads to the implicit declaration of "/=" (see 6.6) is primitive.
Or something like that.
****************************************************************
From: Tucker Taft
Sent: Thursday, October 23, 2008 4:09 PM
Are you sure you don't have too much time on your hands? ;-)
Yes, I agree, it is not easy to prove that the implicitly declared "/="
is a primitive, but it definitely is if the corresponding explicitly
declared "=" is primitive.
Perhaps a "to be honest" in the AARM would be adequate.
6.6 might say that the "implicit" declaration of "/="
is actually considered "explicit" from the point of view of 3.2.3.
We have slowly been trying to rid the language definition of rules that
depend on whether a declaration is explicit or implicit, as they are
almost always troublesome in some corner case like this one.
****************************************************************
Questions? Ask the ACAA Technical Agent