Version 1.2 of acs/ac-00175.txt

Unformatted version of acs/ac-00175.txt version 1.2
Other versions for file acs/ac-00175.txt

!standard 12.5.1(17/2)          09-06-01 AC95-00175/01
!class confirmation 09-06-01
!status received no action 09-06-01
!status received 09-03-09
!subject Interfaces in generic bodies
!summary
!appendix

!topic
!reference RM 12.5.1(17/2), 3.9(2/2)
!from Adam Beneschan 09-03-09
!discussion

My apologies if this is a dumb question; I really haven't looked very closely
into synchronized interfaces and things like that yet.  So I could easily be
missing something.  But: What rule makes the following code illegal?

    package Pack1 is
        type Int is limited interface;
    end Pack1;

    generic
        type T is tagged limited private;
    package Pack2 is
        pragma Elaborate_Body;
    end Pack2;

    package body Pack2 is
        type New_T is new T with record
            F1 : Integer;
        end record;
    end Pack2;

    with Pack1;
    with Pack2;
    package Pack3 is
        task type Task_Type is new Pack1.Int with
            entry E1;
        end Task_Type;
        package New_Pack2 is new Pack2 (Task_Type);
    end Pack3;


3.9(2/2) says that that a task type derived from an interface type is a tagged
type.  12.5.1(17/2) says that for a formal "tagged limited private" type, the
category for the formal is the category of all tagged types; Task_Type is tagged
by 3.9(2), and I don't see any other rules in 12.5.1 that would make Task_Type
an illegal actual for the formal T.  But the result is a type extension being
derived from a task type in the instance body, which is disallowed by
3.9.1(3/2).

Contract model violation?

****************************************************************

From: Randy Brukardt
Date: Monday, March 9, 2009  3:03 PM

The intent is always that regular private types and generic private types have
similar rules. For a regular private type, this is handled by 7.3(7.2-3/2):

    package Pack1 is
        type Int is limited interface;
    end Pack1;

    with Pack1;
    package Pack2 is
        type T is tagged limited private;
    begin
        task type T is new Pack1.Int with -- Illegal by 7.3(7.2-3/2)
             entry E1;
        end Task_Type;
    end Pack2;

Note that this violates *both* parts of 7.3(7.2-3/2).

12.5.1(5.1/2) covers the similar cases for formal derived types; apparently we
forgot that the same can happen for formal privates.

We presumably need a similar matching rule for formal private types. What's not
clear to me is whether we need the "no hidden interfaces" rule for formal
private types. I suspect that we do (I think you can take the examples in 7.3 in
the AARM and make generic version easily enough). In that case, that would be
sufficient to prevent this problem (a type with an interface could not match a
generic formal private type). OTOH, that seems like a pretty nasty restriction.
(I've got some sort of flu bug today, so I may not be making sense...)

****************************************************************

From: Ed Schonberg
Date: Monday, March 9, 2009  3:05 PM

> My apologies if this is a dumb question; I really haven't looked very
> closely into synchronized interfaces and things like that yet.  So I
> could easily be missing something.  But: What rule makes the following
> code illegal?

It's the last few words of 3.9.1 (1/2):

Every type extension is a tagged type, and is a record extension of ...  .or a
non-interface synchronized tagged type.

****************************************************************

From: Randy Brukardt
Date: Monday, March 9, 2009  3:49 PM

Humm, that's a definition, not a legality rule. The same text is given in
3.9(2.1/2), but that is also a definition.

The legality rule 3.9.1(3/2) applies, however. Note that it is rechecked in the
generic specification (so while the generic is legal in Adam's example, the
instance is not).

3.9.1(4/2) disallows type extensions of a generic formal in a generic body.

So, in a modification of Adam's example:

    package Pack1 is
        type Int is limited interface;
    end Pack1;

    generic
        type T is tagged limited private;
    package Pack2 is
        pragma Elaborate_Body;
    end Pack2;

    package body Pack2 is
        type New_T is new T with record -- Illegal by 3.9.1(4/2)
            F1 : Integer;
        end record;
    end Pack2;

    generic
        type T is tagged limited private;
    package Pack3 is
        type New_T is new T with record -- OK by 3.9.1(3/2), but rechecked.
            F1 : Integer;
        end record;
    end Pack3;

    with Pack1;
    with Pack3;
    package Pack4 is
        task type Task_Type is new Pack1.Int with
            entry E1;
        end Task_Type;
        package New_Pack3 is new Pack3 (Task_Type); -- Illegal by 3.9.1(3/2)
    end Pack4;

So, thanks Ed for pointing us in the right direction. (And ignore my earlier
message.)

****************************************************************

From: Adam Beneschan
Date: Monday, March 9, 2009  4:03 PM

> 3.9.1(4/2) disallows type extensions of a generic formal in a generic body.

I forgot about that rule.  And I don't even have a flu to blame...

****************************************************************

Questions? Ask the ACAA Technical Agent